Kos*_*Kos 49 c c++ resources gcc embedded-resource
我正在寻找一种方法来轻松地将任何外部二进制数据嵌入到由GCC编译的C/C++应用程序中.
我想做的一个很好的例子就是处理着色器代码 - 我可以把它保存在源文件中,const char* shader = "source here";
但这是非常不切实际的.
我希望编译器为我做:在编译(链接阶段)时,读取文件"foo.bar"并将其内容链接到我的程序,以便我能够从内容中访问内容作为二进制数据码.
对于我想作为单个.exe文件分发的小型应用程序可能很有用.
GCC是否支持这样的事情?
Mic*_*urr 49
有几种可能性:
使用ld的功能将任何文件转换为对象(使用gcc mingw嵌入二进制blob):
ld -r -b binary -o binary.o foo.bar # then link in binary.o
Run Code Online (Sandbox Code Playgroud)使用bin2c
/ bin2h
实用程序将任何文件转换为字节数组(在代码中嵌入图像,不使用资源部分或外部图像)
更新:这是一个更完整的示例,说明如何使用绑定到可执行文件中的数据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;
}
Run Code Online (Sandbox Code Playgroud)
更新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)
Run Code Online (Sandbox Code Playgroud)
这是一种解决方法,但它运作良好并且不太难看.
Rio*_*iot 24
除了已经提到的建议,在linux下你可以使用十六进制转储工具xxd,它具有生成C头文件的功能:
xxd -i mybinary > myheader.h
Run Code Online (Sandbox Code Playgroud)
iro*_*owe 18
对于 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;
}
Run Code Online (Sandbox Code Playgroud)
目前不存在 C++ 的等效指令。
Mat*_*att 10
该.incbin
GAS指令可用于这项任务.这是一个完全免费的许可库,它包裹着它:
https://github.com/graphitemaster/incbin
回顾一下.incbin方法是这样的.你有一个用gcc -c thing.s编译的thing.s汇编文件
.section .rodata
.global thing
.type thing, @object
.align 4
thing:
.incbin "meh.bin"
thing_end:
.global thing_size
.type thing_size, @object
.align 4
thing_size:
.int thing_end - thing
Run Code Online (Sandbox Code Playgroud)
在您的c或cpp代码中,您可以引用它:
extern const char thing[];
extern const char* thing_end;
extern int thing_size;
Run Code Online (Sandbox Code Playgroud)
那么你将结果.o与其余的编译单元链接起来.感谢@John Ripley及其答案:C/C++与GCC:静态地将资源文件添加到可执行文件/库
但上面的内容并不像incbin给你的那么方便.要使用incbin完成上述操作,您不需要编写任何汇编程序.以下将做:
#include "incbin.h"
INCBIN(thing, "meh.bin");
int main(int argc, char* argv[])
{
// Now use thing
printf("thing=%p\n", gThingData);
printf("thing len=%d\n", gThingSize);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
21756 次 |
最近记录: |