用户定义的资源或其他数据格式 [英] User-defined Resource or other data format

查看:111
本文介绍了用户定义的资源或其他数据格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多数据正在编译成* .lib文件.它基本上等效于具有4000行75列的Excel电子表格.我编写了一个快速例程,该例程读取.cdf(另存为.cdf的.xls),并以具有4,000个元素的结构数组的正确格式编写,每个元素对.cpp具有75个成员,这是我的图书馆项目的一部分.一切正常,我很乐意这样做-用户获得了一个.exe文件.在VC2008中,.lib文件的构建大约需要40分钟,这对我来说不是一个大问题,因为我每年仅需要更改一次数据.仅供参考,.cdf文件是专有的,因此我不想将其分发给可能无意(或有意)修改它的用户,但是.exe文件需要访问数据.

我已经从VS2008迁移到VS2010. .lib文件的构建时间更长(大约50分钟),但是最大的问题是,使用它的.exe文件现在花费的构建时间也一样长(在VS2008中,每个文件花费大约30秒).在相同的项目设置下,VS2010中的时间比VS2008中的时间长约100倍.如果每次我要测试更改都需要50分钟,我将无法对.exe项目(我不断更新并添加到)进行工作.

有人建议我调查一个用户定义的资源,该资源不会被编译,并且会大大缩短构建时间.有没有人知道如何使用.xls,.cdf,.txt等文件作为资源的示例(或者比使用库文件中的结构数组更好的方法)?

预先感谢,
埃德



这是一些示例代码,向您展示我现在的操作方法-谢谢,Ed



I have a lot of data that I was compiling into a *.lib file. It''s basically the equivalent of an Excel spreadsheet with 4,000 rows and 75 columns. I wrote a quick routine that read from a .cdf (.xls saved as .cdf) and wrote in the proper format of an array of structs with 4,000 elements, each element having 75 members to a .cpp which was part of my library project. Everything works fine and I was happy with doing it that way - the user gets a single .exe file. In VC2008, it takes about 40 minutes for the .lib file to build which isn''t a big problem for me because I only need to change the data about once a year. FYI, the .cdf file is proprietary so I don''t want to distribute it to the users who may inadvertently (or purposefully) modify it, but the .exe file needs to have access to the data.

I have migrated from VS2008 to VS2010. The build time for the .lib file is a little longer (about 50 minutes) but the big problem is that the .exe files that use it now take just as long to build (in VS2008, they took about 30 seconds each). That''s about 100 times longer in VS2010 than in VS2008, with the same project settings in both. I can''t be productive with the .exe projects (which I''m constantly updating and adding to) if it''s going to take 50 minutes every time I want to test a change.

Someone suggested that I look into a user-defined resource which wouldn''t be compiled and would significantly speed up my build times. Does anyone have a sample of how to use an .xls, .cdf, .txt, etc. file as a resource (or a better way of doing it than an array of structs in a library file)?

Thanks in advance,
Ed



Here is some sample code to show you how I do it now - Thanks, Ed





//////////////////////////////////////////////////////////////////////////////////////////
//这是一种用于在
之间交换存储的数据的数据结构类型的示例 //.lib文件和.exe文件,并加载到对话框中
//为简化起见,显着缩短-真正的成员有75个成员
//
struct EMDData//位于.lib和.exe都包含的头文件中 {
CString csKey; //键
CString csName; //(例如"PART_0375221")

双dWeight; //重量(磅)
双深度//深度(英寸)

int nFlange; //法兰类型
int nBase; //基本类型
};


//////////////////////////////////////////////////////////////////////////////////////////
//这是.lib项目中的函数,其中包含所有数据
//为简化起见,显着缩短-实际的具有#define NUMNAMES 4125
//并记住EMDData结构具有75个成员
//MY_DATA []数组是由一个简短的例程编写的,该例程从.sdf文件和
中读取 //这样写. .sdf文件类似于:
//
//W2209613 WXPRQTBG 335.0 44.000 21 1001 .....
//W3389512 VYAPSAFH 322.0 43.875 21 1001 ......
//
/******功能getDataFromStruct()******/
BOOL getDataFromStruct(CString csKey,struct EMDData * EData)//文件My_Data.cpp
{

int i;
BOOL bFound = FALSE;

struct EMDData MY_DATA [NUMNAMES];

MY_DATA [0] .csKey = _T("W2290613");
MY_DATA [0] .csName = _T("WXPRQTBG");
MY_DATA [0] .dWeight = 335.0000;
MY_DATA [0] .dDepth = 44.0000;
MY_DATA [0] .nFlange = 21;
MY_DATA [0] .nBase = 1001;

MY_DATA [1] .csKey = _T("W3389512");
MY_DATA [1] .csName = _T("VYAPSAFH");
MY_DATA [1] .dWeight = 322.0000;
MY_DATA [1] .dDepth = 43.8750;
MY_DATA [1] .nFlange = 21;
MY_DATA [1] .nBase = 1001;

//->继续通过MY_DATA [4124]

for(i = 0; i< numnames; i ++)>
if(MY_DATA [i] .csKey.Compare(csKey)== 0){

EData-> csKey = MY_DATA [i] .csType;
EData-> csName = MY_DATA [i] .csName;
EData-> dWeight = MY_DATA [i] .dWeight;
EData-> dDepth = MY_DATA [i] .dDepth;
EData-> nFlange = MY_DATA [i] .nFlange;
EData-> nBase = MY_DATA [i] .nBase;

bFound = TRUE;
休息;

}
}

return bFound;

}/*函数getDataFromStruct()的结尾*/


//////////////////////////////////////////////////////////////////////////////////////////
//从.exe文件中,从用户选择零件的对话框中,我将有一个
//如下所示:
//

if(getDataFromStruct(m_csPart,& EData){
//->加载对话框
//等....
} else {
EMDAlert(_T(错误469:未检索到数据."));
//等....
}



////////////////////////////////////////////////////////////////////////////////////////
// This is a sample of the kind data structure I use to exchange stored data between the
// .lib file and the .exe file, and load into a dialog
// Significantly shortened for simplicity - the real one has 75 members
//
struct EMDData // in a header file #included in both the .lib and the .exe
{
CString csKey; // The key
CString csName; // (e.g. "PART_0375221")

double dWeight; // Weight (lbs)
double dDepth; // Depth (in)

int nFlange; // Flange type
int nBase; // Base type
};


////////////////////////////////////////////////////////////////////////////////////////
// Here''s the Function from the .lib project that has all the data
// Significantly shortened for simpliity - the real one has #define NUMNAMES 4125
// and remember the EMDData struct has 75 members
// The MY_DATA[] array was written by a short routine that read from an .sdf file and
// wrote it this way. The .sdf file is like:
//
// W2209613 WXPRQTBG 335.0 44.000 21 1001 .....
// W3389512 VYAPSAFH 322.0 43.875 21 1001 ......
//
/****** FUNCTION getDataFromStruct() ******/
BOOL getDataFromStruct(CString csKey, struct EMDData *EData) // in file My_Data.cpp
{

int i;
BOOL bFound = FALSE;

struct EMDData MY_DATA[NUMNAMES];

MY_DATA[0].csKey = _T("W2290613");
MY_DATA[0].csName = _T("WXPRQTBG");
MY_DATA[0].dWeight = 335.0000;
MY_DATA[0].dDepth = 44.0000;
MY_DATA[0].nFlange = 21;
MY_DATA[0].nBase = 1001;

MY_DATA[1].csKey = _T("W3389512");
MY_DATA[1].csName = _T("VYAPSAFH");
MY_DATA[1].dWeight = 322.0000;
MY_DATA[1].dDepth = 43.8750;
MY_DATA[1].nFlange = 21;
MY_DATA[1].nBase = 1001;

// -> continues through MY_DATA[4124]

for(i=0;i<numnames;i++)>
if(MY_DATA[i].csKey.Compare(csKey) == 0) {

EData->csKey = MY_DATA[i].csType;
EData->csName = MY_DATA[i].csName;
EData->dWeight = MY_DATA[i].dWeight;
EData->dDepth = MY_DATA[i].dDepth;
EData->nFlange = MY_DATA[i].nFlange;
EData->nBase = MY_DATA[i].nBase;

bFound = TRUE;
break;

}
}

return bFound;

} /* end of function getDataFromStruct() */


////////////////////////////////////////////////////////////////////////////////////////
// From the .exe file, from a dialog where the user selects the Part, I would have a
// something like the following:
//

if(getDataFromStruct(m_csPart, &EData) {
// -> load the dialog box
// etc.....
} else {
EMDAlert(_T("Error 469: Data not retrieved."));
// etc.....
}



推荐答案

在应用程序的.rc2文件中,您将放置数据文件的include指令作为资源:

In the .rc2 file of your application you would place an include directive for your data file as resource:

MyResName   CDF	    DISCARDABLE		"MyFileName.cdf"



您的.cdf文件可以包含文本或二进制数据,就像您喜欢的一样.然后,该文件将由资源编译器/链接器放置在.exe文件中.

要从程序中访问该资源,请使用如下序列:



Your .cdf file can contain text or binary data, just as you like. This file will then be placed by the resource compiler / linker inside your .exe file.

To access that resource from your program, you use a sequence like this:

HRSRC hrc = FindResource (hInst, "MyResName", "CDF");
if (hrc == NULL)
    return false;
HGLOBAL hgb = LoadResource (hInst, hrc);
if (hgb == NULL)
    return false;
LPVOID prsrc = LockResource (hgb);
UINT size = SizeofResource (hInst, hrc);



其中hInst是.exe文件的实例句柄,该文件是CWinApp对象的m_hInstance成员.如果将代码放在主程序中,甚至可以将NULL用作hInst,然后默认将其搜索为Windows用于启动该进程的exe/dll文件.

现在,您有了一个指向数据的指针和一个以字节为单位的大小.就这么简单.

祝你好运.

修改:在了解您的生成过程如何工作之后,我建议您执行以下步骤:

1.如上所述,将.sdf文件作为资源放入程序中

2.采用该小函数,该函数读取您的.sdf并生成.lib文件的源,并以稍微修改的方式将其包含在您的主程序中.现在,它应该从包含的资源中读取该资源,这对于它来说是一个很大的字符串缓冲区.将该prsrc转换为PCSTR并将其提供给您的功能.您将要做的主要修改是:

使函数从字符串而不是文件中读取(应该很简单),然后让它直接填充MY_DATA结构而不是生成代码行.因此,实际上是该功能的简化.

3.程序启动时,如上所示查找资源,并调用prsrc函数,并使其填充MY_DATA数组(现在必须将其放置在主程序中而不是库中).

完成所有工作后,您可以开始考虑对资源进行加密,这也是一个相对容易的任务.

让我知道您如何处理此问题,方法是粘贴对此解决方案的回复(这样我会收到电子邮件通知),并在需要时寻求帮助.



where hInst is the instance handle of your .exe file, which is the m_hInstance member of your CWinApp object. If you place that code in your main program you can even use NULL as hInst, which then defaults to searching the exe/dll file that Windows used to start the process.

Now you have a pointer to your data and a size in bytes. Its as simple as that.

Good luck.

AMENDED: After seeing how your generation process works I would recommend the following steps:

1. Put the .sdf file as resource in your program as described above

2. Take that little function that reads your .sdf and generates the source of your .lib file and include it in a slightly modified way in your main program. It should now read from the included resource, which appears as a big string buffer to it. Cast that prsrc to a PCSTR and give that to your function. The main modification you will have to do is:

Make your function read from a string instead of a file (that should be simple) and let it populate the MY_DATA structure directly instead of generating code lines. Thus it''s in fact a simplification of that function.

3. When your program starts locate the resource as shown above and call your function the prsrc and let it fill your MY_DATA array (which must now be placed in your main program instead of the library).

When all that works you can start thinking about encrypting the resource, which is also a relatively easy task.

Let me know how you get on with it by pasting a reply to this solution (so I get an e-mail notification) and call for help if you need any.


在某种资源上,将数据编译成DLL然后导出指向它的指针可能会带来一些麻烦.由于您不必将静态数据链接到每个EXE(您所需要的只是一个指向要为数据提供多少个访问点的指针),因此构建速度可能会更快.

坦白地说,我还没有看到VC ++ 2010的链接时间来临时.链接时,您的系统是否会发生很多抖动?如果这样做的话,可能值得抓住一些额外的RAM,看看是否有任何效果.

干杯,

Ash
As well as looking at a resource you might get some milage out of compiling your data into a DLL and then exporting a pointer to it. As you won''t have to link the static data into each EXE (all you need is a pointer to how ever many access points you want for the data) the build will probably be faster.

To be honest I haven''t seen link times go through the roof with VC++2010. Does your system thrash a lot when it''s linking? If it does then it might be worth grabbing some extra RAM and seeing if that has any effect.

Cheers,

Ash


谢谢大家的评论.它比我的技能水平略高一点,但这并不意味着我不能再自学了.最后一个问题,当我有了指向数据的指针时,例如,我将如何访问第十行第十二列中的信息?仅供参考,第一列是关键,因此我将首先搜索该列,知道我在哪一行,然后获取我需要的任何列.

我还将研究加密数据,以便可以对其进行简单搜索.

再次谢谢大家,
埃德

PS.我当前的系统是XP-Pro SP-3.我本周要购买一台装有Windows 7和12 MB ram的新机器,我希望编译器会更快.我不知道为什么在VC2008和VC2010之间过渡时会遇到如此艰难的时刻-再次感谢.
Thank you all for your comments. It''s a little above my skill level but that doesn''t mean I can''t teach myself a little more. One last question, once I have a pointer to the data, how would I, for example, access the information in the 10th row, 12th column? FYI, the first column is a key so I would search that first, know what row I''m in, and then grab whatever column I needed.

I will also look into encrypting the data so I can do a simple search on it.

Thank you all again,
Ed

PS. My current system is XP-Pro, SP-3. I''m getting a new machine this week with Windows 7 and 12 MB of ram, and I''m hoping the compiler will be much faster. I don''t know why I''m having such a difficult time in the transition between VC2008 and VC2010 - thanks again.


这篇关于用户定义的资源或其他数据格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆