使用 GCC 在可执行文件中嵌入资源

新手上路,请多包涵

我正在寻找一种方法来轻松地将任何外部二进制数据嵌入到由 GCC 编译的 C/C++ 应用程序中。

我想做的一个很好的例子是处理着色器代码——我可以把它保存在像 const char* shader = "source here"; 这样的源文件中,但这是非常不切实际的。

我希望编译器为我做这件事:在编译(链接阶段)时,读取文件“foo.bar”并将其内容链接到我的程序,这样我就可以从代码。

对于我想作为单个 .exe 文件分发的小型应用程序可能很有用。

GCC 支持这样的东西吗?

原文由 Kos 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

有几种可能性:

   ld -r -b binary -o binary.o foo.bar  # then link in binary.o


更新:这是一个更完整的示例,说明如何使用 ld -r -b binary 将数据绑定到可执行文件中:

 #include <stdio.h>

// a file named foo.bar with some example text is 'imported' into
// an object file using the following command:
//
//      ld -r -b binary -o foo.bar.o foo.bar
//
// That creates an bject file named "foo.bar.o" with the following
// symbols:
//
//      _binary_foo_bar_start
//      _binary_foo_bar_end
//      _binary_foo_bar_size
//
// Note that the symbols are addresses (so for example, to get the
// size value, you have to get the address of the _binary_foo_bar_size
// symbol).
//
// In my example, foo.bar is a simple text file, and this program will
// dump the contents of that file which has been linked in by specifying
// foo.bar.o as an object file input to the linker when the progrma is built

extern char _binary_foo_bar_start[];
extern char _binary_foo_bar_end[];

int main(void)
{
    printf( "address of start: %p\n", &_binary_foo_bar_start);
    printf( "address of end: %p\n", &_binary_foo_bar_end);

    for (char* p = _binary_foo_bar_start; p != _binary_foo_bar_end; ++p) {
        putchar( *p);
    }

    return 0;
}


更新 2 - 获取资源大小:我无法正确读取 _binary_foo_bar_size。在运行时,gdb 使用 display (unsigned int)&_binary_foo_bar_size 向我显示文本资源的正确大小。但是将其分配给变量总是会给出错误的值。我可以通过以下方式解决此问题:

 unsigned int iSize =  (unsigned int)(&_binary_foo_bar_end - &_binary_foo_bar_start)

这是一种解决方法,但效果很好并且不太难看。

原文由 Michael Burr 发布,翻译遵循 CC BY-SA 3.0 许可协议

对于 C23,现在存在预处理器指令 #embed ,它可以在不使用外部工具的情况下实现您正在寻找的内容。请参阅 C23 标准的 6.10.3.1(这里是最新 工作草案 的链接)。这是关于 #embed 历史的 一篇好博 文,作者是这个新功能背后的一位委员会成员。

这是标准草案中的一个片段,展示了它的使用:

 #include <stddef.h>
void have_you_any_wool(const unsigned char*, size_t);

int main (int, char*[]) {
    static const unsigned char baa_baa[] = {
#embed "black_sheep.ico"
    };

    have_you_any_wool(baa_baa, sizeof(baa_baa));
    return 0;
}

目前不存在 C++ 的等效指令。

原文由 irowe 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题