我有一个在C++中编译的文件,我希望其中有一个字符串其值为编译时文件的内容。
换句话说,我想要#include该文件,但该文件应该被包含在双引号内。
我该如何在C++中实现这一点?
如果该文件的文本中包含双引号,我该如何转义它们?
您可以使用xxd -i /tmp/your_file > /tmp/your_file_as_string.c
命令,它会为您定义一个字符串字面量:
$ cat /tmp/your_file_as_string.c
unsigned char _tmp_inc[] = {
0x2e, 0x2f, 0x42, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x6e, 0x65, 0x78, 0x74,
0x4f, 0x6f, 0x6c, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f,
...
0x74, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x65, 0x63,
0x0a
};
unsigned int _tmp_inc_len = 1513;
如果要正确地在字符串中创建带有正确的空终止符的标题,请使用sed:
xxd -i ${INPUT_FILE_NAME} | sed s/}\;/,0x00}\;/ > ${INPUT_FILE_PATH}.h
我能想到的唯一方法是在编译之前生成另一个文件。你可以构建一个小型实用程序来为你完成这项任务。该实用程序可以处理双引号,并且你可以在构建文件中在编译之前调用它。
一个显而易见(但有点幼稚)的方法是进行系统调用并调用cpp -x c++ file.cpp
,然后直接将流的内容读入字符串中,就像您执行任何其他文件读取操作一样。
这将在C++模式下调用C预处理器对file.cpp
进行处理,这与运行#include ...
完全相同。然后将该值存储在string
对象中。
请尝试查看一下你的编译器/链接器套件是否有一个名为 bin2obj
的程序。如果存在,它通常可以将任何文件生成一个.o
或.obj
文件,你可以指示链接器将其链接到你的程序中。(如何完成此步骤取决于构建环境。)
通常情况下,你将最终得到一个或两个符号,可以通过以下方式使其在代码中可见:
extern "C" const char * myFile_start;
extern "C" unsigned int myFile_size;
链接器会确保myFile_start
指向文件的开头,而myFile_size
则提供文件长度的指示。
符号名称可能会有所变化:您可以使用objdump
、nm
或dumpbin
等实用程序(再次取决于编译器/链接器套件)来调查生成的.o
或.obj
文件以查找符号名称(如果它们尚未在您的obj2bin
工具文档中记录)。
请注意,这会膨胀可执行文件(通常为.data
或.rodata
部分或等效部分),这可能是某些平台上的问题。
(如果您没有bin2obj,则可以通过在搜索引擎上寻找带有您的编译器/IDE名称的“bin2obj”来找到它。)