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

How to cross-platformly build binary resources into program?

本文关键字:程序 构建 资源 跨平台 二进制      更新时间:2023-10-16

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

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

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

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

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

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

  • 使用 WinAPI 获取资源需要许多函数来访问一个资源。Windows中是否有更简单的方法?
  • 如何在Mac中做到这一点?

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

窗户:

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上的防病毒软件有时不喜欢它。可能有更好的解决方案。