我有一个项目需要可执行文件中的一堆图形文件。由于目标没有文件系统,我不能只使用该fopen
功能。一种方法是将文件内容转换为包含变量定义的 C 源代码,如下所示
unsigned char file1_content[] = {
0x01, 0x02, ...
};
即使使用转换器工具来构建此类文件也很麻烦。
有没有办法在为每个文件指定变量名的同时将二进制文件添加到 rdata 部分?我考虑为此使用链接器脚本,但没有找到方法。
我有一个项目需要可执行文件中的一堆图形文件。由于目标没有文件系统,我不能只使用该fopen
功能。一种方法是将文件内容转换为包含变量定义的 C 源代码,如下所示
unsigned char file1_content[] = {
0x01, 0x02, ...
};
即使使用转换器工具来构建此类文件也很麻烦。
有没有办法在为每个文件指定变量名的同时将二进制文件添加到 rdata 部分?我考虑为此使用链接器脚本,但没有找到方法。
使用工具并不是特别麻烦,这是经典的解决方案。搜索“bin2c”找到一些。
您只需在构建过程中包含这些“资产构建”步骤,即从 Makefile 调用该工具。这也意味着该工具仅在源数据发生更改时才运行,这很好。
至少 GNU 链接器 (LD) 似乎能够将文件放置在输出文件的各个部分中(请参阅Section Placement 文档,如下所示:
.data : { afile.o bfile.o cfile.o }
但这听起来很麻烦,并且需要您考虑可执行文件中通常有点太低级的部分。此外,它似乎要求输入是目标文件,这使得问题循环,因为通用二进制资产不是链接器兼容的目标文件。
我建议使用 bin2c 方法。
您可以使用链接器选项--format
以及-Wl,
将其传递给链接器,例如:
gcc -Wl,--format=binary -Wl,myfile.bin -Wl,--format=default
最后设置格式为默认允许您将链接器切换回标准输入格式。
您可以通过简单的_binary_myfile_bin_start
汇编符号(for myfile.bin
, for xxx.yyy
it will be _binary_xxx_yyy_start
and _binary_xxx_yyy_end
)从源代码访问二进制资源,例如:
extern uint8_t data[] asm("_binary_myfile_bin_start");
以及下次使用data
。最好是自己做 objcopy,或者使用资源黑客。
UPD:用一个小例子进行扩展—— main 输出它自己的目标文件的前四个字节:
#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