如何跨平台将二进制资源构建到程序中?

时间:2018-10-26 02:06:41

标签: c++ embedded-resource

我们正在为Windows,Mac和Linux开发C ++应用程序。该应用程序具有许多二进制资源,出于某种原因,我们需要将它们打包在可执行二进制文件中,而不是放在目录(或Apple App捆绑包)中。

当前,我们使用脚本将这些资源转换为C ++数组常量,然后进行编译和链接。但是,这种方法有很多缺陷:

  • 您必须编译资源源代码,这需要时间,并且在本质上是不必要的。
  • 资源源代码将由IDE解析。由于它们很大,因此代码分析速度大大降低。
  • MSVC对源代码的大小有限制,因此必须将大量资源(几个MB)分成很多部分,然后在运行时进行连接。

经过研究,我找到了一些解决方案:

  • 在Windows中,我可以使用 .rc 文件和相关的WinAPI。
  • 在Linux中,我可以通过objcopy将任意二进制文件直接转换为 obj 文件。

但是,仍然存在一些问题:

  • 使用WinAPI来获取资源需要许多功能来访问一个资源。 Windows中有没有更简单的方法?
  • 在Mac中如何做到?

1 个答案:

答案 0 :(得分:1)

一个很常见的技巧是将资源附加到可执行文件的末尾,这是最常用的自解压存档或脚本语言的可执行文件编译器。

Windows:

copy app.exe+all-resources app-with-resources.exe

Linux:

cp executable executable-with-resources
cat all-resources >>executable-with-resources

然后,您可以使用fopen(argv[0])读取自己的可执行文件。 为了跳到正确的位置(即资源的开头),一种可能的解决方案是将不包含资源的可执行文件的大小存储为文件的最后一个字。

FILE* fp = fopen(argv[0], "rb");
fseek(fp, -sizeof(int), SEEK_END);
int beginResourcesOffset;
fread(&beginResourcesOffset, 1, sizeof(int), fp);
fseek(fp, beginResourcesOffset, SEEK_SET);

但是请谨慎使用此解决方案,因为Windows上的防病毒有时不喜欢它。可能有更好的解决方案。