我有一个项目,需要在可执行文件中的一堆图形文件。由于没有目标文件系统,我无法使用fopen
函数。一种方法是将文件的内容转换为包含变量定义,比如如何添加二进制资源
unsigned char file1_content[] = {
0x01, 0x02, ...
};
这是麻烦的,建立这样的文件,即使有一个转换工具的C语言源程序。
有没有什么办法可以将二进制文件添加到rdata部分,同时为每个文件指定一个变量名?我想为此使用链接脚本,但没有找到办法。
我有一个项目,需要在可执行文件中的一堆图形文件。由于没有目标文件系统,我无法使用fopen
函数。一种方法是将文件的内容转换为包含变量定义,比如如何添加二进制资源
unsigned char file1_content[] = {
0x01, 0x02, ...
};
这是麻烦的,建立这样的文件,即使有一个转换工具的C语言源程序。
有没有什么办法可以将二进制文件添加到rdata部分,同时为每个文件指定一个变量名?我想为此使用链接脚本,但没有找到办法。
这对工具来说并不是特别麻烦,而这就是经典的解决方案。 Search for "bin2c"找一些。
您只需在构建过程中包含这些“资产构建”步骤,即从Makefile调用该工具。这也意味着该工具只在源数据发生变化时才运行,这很好。
至少GNU链接器(LD)似乎能够将文件放置到输出文件的部分(见Section Placement documentation,像这样:
.data : { afile.o bfile.o cfile.o }
但是这听起来很麻烦,它需要你考虑一下可执行文件中经常有点低级的部分,并且它似乎要求输入是目标文件,这是由于通用二进制资源不是链接器-compatible object file。
我会推荐使用bin2c方法。
您可以沿着使用链接器选项--format
与-Wl,
将它传递给连接器,如:
gcc -Wl,--format=binary -Wl,myfile.bin -Wl,--format=default
最后设置格式默认允许你切换连接回标准输入格式。
您可以通过简单的_binary_myfile_bin_start
汇编符号访问来源的二进制资源(myfile.bin
,为xxx.yyy
这将是_binary_xxx_yyy_start
和_binary_xxx_yyy_end
),如:
而且下次使用data
。你自己做objcopy或者使用资源黑客好得多。
UPD:用一个小例子扩大 - 主输出前四个字节自己的对象文件:
#include "stdio.h"
#include "stdint.h"
extern uint8_t data[] asm("_binary_main_o_start");
int
main(void)
{
fprintf(stdout, "0x%x, 0x%x, 0x%x, 0x%x\n", data[0], data[1], data[2], data[3]);
return 0;
}
现在编译运行:
$ gcc -o main.o -c main.c
$ gcc -o main main.o -Wl,--format=binary -Wl,main.o -Wl,--format=default
$ ./main
0x7f, 0x45, 0x4c, 0x46
如何我不会让xxx_end符号或二进制文件的大小? – harper
数据结束被链接器标记为“_binary_xxx_yyy_end”,大小被标记为“_binary_xxx_yyy_size” –
我可以创建包含从二进制文件构建的元素的库(.ar)吗?最后我想链接这个二进制文件库。 – harper