我正在尝试将二进制blob嵌入到exe文件中。我正在使用mingw gcc。
我像这样制作目标文件:
ld -r -b binary -o binary.o input.txt
然后我查看objdump输出以获取符号:
objdump -x binary.o
它给出了符号:
的符号_binary_input_txt_start
_binary_input_txt_end
_binary_input_txt_size
然后我尝试在我的C程序中访问它们:
#include <stdlib.h>
#include <stdio.h>
extern char _binary_input_txt_start[];
int main (int argc, char *argv[])
{
char *p;
p = _binary_input_txt_start;
return 0;
}
然后我这样编译:
gcc -o test.exe test.c binary.o
但我总是得到:
undefined reference to _binary_input_txt_start
有谁知道我做错了什么?
答案 0 :(得分:30)
在你的C程序中删除前导下划线:
#include <stdlib.h>
#include <stdio.h>
extern char binary_input_txt_start[];
int main (int argc, char *argv[])
{
char *p;
p = binary_input_txt_start;
return 0;
}
C编译器经常(总是?)似乎在extern
名称前加下划线。我不完全确定为什么会这样 - 我认为this wikipedia article's声称有一些事实
C编译器通常会在所有外部作用域程序标识符前面加上一个前导下划线,以避免与运行时语言支持的贡献发生冲突
但令我感到震惊的是,如果将下划线添加到所有外部,那么你并没有真正对命名空间进行分区。无论如何,这是另一天的问题,事实是下划线确实被添加了。
答案 1 :(得分:4)
我在Linux(Ubuntu 10.10)中测试过它。
资源文件:
input.txt中
gcc(Ubuntu / Linaro 4.4.4-14ubuntu5)4.4.5 [为Linux生成ELF可执行文件]
生成符号_binary__input_txt_start
接受符号_binary__input_txt_start
(带下划线)。
i586-mingw32msvc-gcc(GCC)4.2.1-sjlj(mingw32-2)[为Windows生成PE可执行文件]
生成符号_binary__input_txt_start
接受符号binary__input_txt_start
(不带下划线)。
答案 2 :(得分:4)
来自ld man page:
<强> - 领先下划线强>
<强> - 无前导下划线强>
对于大多数目标,默认符号前缀是下划线,并在目标的描述中定义。通过此选项,可以禁用/启用默认下划线符号前缀。
所以
ld -r -b binary -o binary.o input.txt --leading-underscore
应该是解决方案。
答案 3 :(得分:0)
显然这个功能在OSX的ld中不存在,所以你必须使用他们添加的自定义gcc标志totally differently,并且你不能直接引用数据,但必须做一些运行时初始化到得到地址。
因此,使自己成为汇编源文件可能更具可移植性,该文件在构建时包含二进制文件,即this answer。