LoadString,静态库和可执行文件

时间:2010-02-01 19:40:50

标签: c++ visual-studio localization resources

我的项目已设置好所有框架代码和模块都编译为静态.lib(让我们称之为framework.lib),许多测试项目使用framework.lib并编译成可执行文件。

对于错误处理,我正在尝试将资源字符串放在framework.rcframework.lib项目的一部分)中,并将字符串加载到可执行文件中。但是,LoadString()失败了。使用GetLastError() / FormatMessage()我收到以下消息:

“在图像文件中找不到指定的资源类型。”

以下是我如何调用LoadString,它返回0:

char szString[256];  
int iNbOfChars = LoadStringA(GetModuleHandle(NULL), iStringID, szString, 256);

我应该失败,因为资源没有在应用程序中定义,而是在lib中?如果是这样,任何建议,以便我可以拥有一个集中的资源文件?

5 个答案:

答案 0 :(得分:3)

静态库只是.OBJ文件的连接 - 它们没有像资源这样的功能。为此,您需要将资源放在DLL中。

答案 1 :(得分:1)

您无法将资源放入.lib文件中。 (我希望你可以)。当你链接到lib时,你必须保留.rc文件并将它们包含在应用程序的.rc文件中。

因此,您必须确保应用程序也不会使用.lib使用的任何资源ID。这是一团糟,但如果你使用.rc文件作为你的字符串,没有更好的解决方案。并坚持使用微软的工具。

大约几年前,我对此限制感到非常沮丧,我开始构建一个工具,将已编译的资源文件(.res)转换为.obj文件,因此我可以将其包含在我的lib中。当然,当你这样做时,你不能再使用LoadString,但事实证明,编写自己的代码来解析大量的.res数据并找到字符串并不是那么难。所以我目前将字符串放入库中的解决方案是

  • 创建framework.rc
  • 将其编译成framework.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的小细节。