如何在程序中包含数据对象文件(图像等)并访问符号?

时间:2023-04-13
本文介绍了如何在程序中包含数据对象文件(图像等)并访问符号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我已经使用 objcopy 将几个资源文件转换为 .obj 文件,并将它们与我的程序源代码链接起来.我可以使用以下代码很好地访问程序中目标文件中的符号,但只能使用 GCC/G++ (Cygwin):

I've turned a couple of resource files into .obj files using objcopy and i link them with my programs source code. I can very well access the symbols inside the object file in my program with the following code, but only with GCC/G++ (Cygwin):

extern uint8_t data[]   asm("_binary_Resources_0_png_start");
extern uint8_t size[]   asm("_binary_Resources_0_png_size");
extern uint8_t end[]    asm("_binary_Resources_0_png_end");

代码在 Visual Studio 中不起作用,可能是因为 VS 有它自己的 __asm 命令.我想通过链接将我的程序资源(图像、着色器等)包含在我最终可执行文件的 .data 部分中.

The code doesn't work in Visual Studio, probably because VS has it's own __asm command. I want to include my programs resources (Images, Shaders, etc.) in my final executable's .data section through linking them.

但是我如何在 VC++ 中访问目标文件中定义的符号?我在没有汇编命令的情况下尝试了 extern uint8_t _binary_Resources_0_png_start[]extern "C" uint8_t _binary_Resources_0_png_start[] ,但我得到了未解决的符号链接错误.

But how can i access the symbols defined in the object file in VC++? I tried extern uint8_t _binary_Resources_0_png_start[] or extern "C" uint8_t _binary_Resources_0_png_start[] without the assembly command, but i get unresolved symbol link errors.

推荐答案

在解决和测试不同的事情之后,我回到了我原来的方法(链接),它就像魔法一样工作,这里是细节:

After working around and testing different things, i came back to my original approach (linking) and it worked like magic, here is the details:

为了在最终可执行文件的 .data 部分中包含数据,您需要首先将该数据文件(可以是任意二进制文件(任何东西!))转换为可链接的文件格式,也称为目标文件.

In order to include data in the final executable's .data section, you need to first turn that data files (which could be an arbitrary binary file (anything!)) into a linkable file format, also known as an object file.

工具 objcopy 包含在 GNU Binutils 中,可通过 CygwinMinGW 在 windows 中访问,获取一个文件并生成一个目标文件.objcopy 在生成目标文件之前需要了解两件事,输出文件格式和输出架构.为了确定这两件事,我使用工具 objdump 来检查一个有效的可链接目标文件:

The tool objcopy which is included in GNU Binutils and is accessible in windows through Cygwin or MinGW, takes a file and produces an object file. objcopy requires two things to know before generating the object file, the output file format and the output architecture. In order to determine these two things, i check a valid linkable object file with the tool objdump:

objdump -f main.o

这给了我以下信息:

main.o:     file format pe-x86-64
architecture: i386:x86-64, flags 0x00000039:
HAS_RELOC, HAS_DEBUG, HAS_SYMS, HAS_LOCALS
start address 0x0000000000000000

有了这些知识,我现在可以创建目标文件了:

With this knowledge now i can create the object file:

objcopy -I binary -O pe-x86-64 -B i386 data_file.data data_file_data.o

为了处理大量文件,批处理文件可以派上用场.

In order to handle large number of files, batch files could come in handy.

然后我简单地将生成的目标文件与我的程序源链接在一起,并通过符号取消引用 objcopy 生成的指针,其名称可以很容易地被查询:

I then simply link the produced object file(s) together with my programs source and dereference the pointers that objcopy generated, through the symbols, whose names could easily be queried with:

objdump -t data_file_data.o

结果:

data_file_data.o:     file format pe-x86-64

SYMBOL TABLE:
[  0](sec  1)(fl 0x00)(ty  0)(scl  2) (nx 0) 0x0000000000000000 _binary_data_file_data_start
[  1](sec  1)(fl 0x00)(ty  0)(scl  2) (nx 0) 0x0000000000000006 _binary_data_file_data_end
[  2](sec -1)(fl 0x00)(ty  0)(scl  2) (nx 0) 0x0000000000000006 _binary_data_file_data_size

实际上,以下代码适用于 GCC/G++:

Practically speaking, the following code works with GCC/G++:

extern uint8_t data[]   asm("_binary_data_file_data_start");
extern uint8_t end[]    asm("_binary_data_file_data_end");

以下与 MSVC++:

extern "C" uint8_t _binary_data_file_data_start[]; // Same name as symbol
extern "C" uint8_t _binary_data_file_data_end[];   // Same name as symbol

每个文件的大小计算方式为:

The size of each each file is calculated with:

_binary_data_file_data_end - _binary_data_file_data_start

例如,您可以将数据写回文件:

You could for example write the data back into a file:

FILE* file;

file = fopen("data_file_reproduced.data", "wb");
fwrite(_binary_data_file_data_start,                               //Pointer to data
       1,                                                          //Write block size
       _binary_data_file_data_end - _binary_data_file_data_start,  //Data size
       file);

fclose(file);

这篇关于如何在程序中包含数据对象文件(图像等)并访问符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:将 ADC(带进位相加)组装到 C++ 下一篇:为什么可以在寄存器中传递 T*,而 unique_ptr<T>不能?

相关文章