正如另一个关于objcopy
的问题所证明的那样,将二进制文件包含到可执行文件中的另一种方法是使用.incbin
汇编程序指令。这个解决方案有两个主要优点objcopy
:开发人员可以控制符号名称(objcopy
似乎有一个固定的命名方案),而且,它不需要objcopy
.
与基于链接器的解决方案相比,该解决方案还具有优势-sectcreate
。它是跨平台的,访问数据要简单得多。
我正在使用这个 Xcode 构建规则脚本来生成要包含的文件和带有.incbin
指令的程序集文件:
my_generation_tool -o $DERIVED_FILE_DIR/$INPUT_FILE_NAME.out $INPUT_FILE_PATH
export AS_PATH=$DERIVED_FILE_DIR/$INPUT_FILE_NAME.out.s
echo "\t.global _data_start_$INPUT_FILE_BASE" > $AS_PATH
echo "\t.global _data_end_$INPUT_FILE_BASE" >> $AS_PATH
echo "_data_start_ $INPUT_FILE_BASE:" >> $AS_PATH
echo "\t.incbin \"$INPUT_FILE_NAME.out\"" >> $AS_PATH
echo "_data_end_$INPUT_FILE_BASE:" >> $AS_PATH
然后,给定一个使用此规则处理的文件“somefile.gen”,程序集将如下所示:
.global _data_start_somefile
.global _data_end_somefile
_data_start_somefile:
.incbin "somefile.gen.out"
_data_end_somefile:
可以使用data_start_somefile
和data_end_somefile
符号在 C 中访问数据(macOS 链接器在 C 名称前加上一个 spurious _
,这就是程序集文件有它们的原因):
extern char data_start_somefile, data_end_somefile;
for (const char* c = &data_start_somefile; c != &data_end_somefile; ++c)
{
// do something with character
}
另一个线程上的答案有更多的花里胡哨,有些人可能会觉得有用(例如,一个length
符号)。