我的项目已设置好所有框架代码和模块都编译为静态.lib(让我们称之为framework.lib
),许多测试项目使用framework.lib并编译成可执行文件。
对于错误处理,我正在尝试将资源字符串放在framework.rc
(framework.lib
项目的一部分)中,并将字符串加载到可执行文件中。但是,LoadString()
失败了。使用GetLastError()
/ FormatMessage()
我收到以下消息:
“在图像文件中找不到指定的资源类型。”
以下是我如何调用LoadString
,它返回0:
char szString[256];
int iNbOfChars = LoadStringA(GetModuleHandle(NULL), iStringID, szString, 256);
我应该失败,因为资源没有在应用程序中定义,而是在lib中?如果是这样,任何建议,以便我可以拥有一个集中的资源文件?
答案 0 :(得分:3)
静态库只是.OBJ文件的连接 - 它们没有像资源这样的功能。为此,您需要将资源放在DLL中。
答案 1 :(得分:1)
您无法将资源放入.lib文件中。 (我希望你可以)。当你链接到lib时,你必须保留.rc文件并将它们包含在应用程序的.rc文件中。
因此,您必须确保应用程序也不会使用.lib使用的任何资源ID。这是一团糟,但如果你使用.rc文件作为你的字符串,没有更好的解决方案。并坚持使用微软的工具。
大约几年前,我对此限制感到非常沮丧,我开始构建一个工具,将已编译的资源文件(.res)转换为.obj文件,因此我可以将其包含在我的lib中。当然,当你这样做时,你不能再使用LoadString
,但事实证明,编写自己的代码来解析大量的.res数据并找到字符串并不是那么难。所以我目前将字符串放入库中的解决方案是
将framework.res转换为包含外部符号的framework.obj
const BYTE framework_res[];
const size_t framework_res_size;
在提取库中的字符串时使用MyLoadString(framework_res, framework_res_size, iStringId, sz, 256)
而不是LoadString。
这样做的一个好处就是当我编写自己的LoadString时,我可以返回指向资源字符串的指针,而不是复制它。所以我的实际LoadString函数看起来像这样。
LPCWSTR MyFindString(framework_res, framework_res_size, iStringId);
如果使用/ n选项编译.rc文件,它将使null终止所有字符串。
答案 2 :(得分:0)
您可以在应用程序的资源文件中使用#include
指令来包含lib的资源文件。
仅允许在输出(EXE)级别使用资源,并且不能将其嵌入到.Lib中。
答案 3 :(得分:0)
AFAIK您无法将资源添加到静态库 - 您必须将它们编译为DLL以共享或直接进入应用程序。
您可以从中心位置共享.rc并将其编译到应用程序本身。
答案 4 :(得分:0)
集中资源的显而易见的方法是创建包含资源的DLL。然后你可以使用LoadString
,就像资源在可执行文件中一样,除了你需要指定正确的模块句柄而不是NULL的小细节。