我正在寻找一种方法来轻松地将任何外部二进制数据嵌入到由GCC编译的C/C++应用程序中.
我想做的一个很好的例子就是处理着色器代码 - 我可以把它保存在源文件中,const char* shader = "source here";
但这是非常不切实际的.
我希望编译器为我做:在编译(链接阶段)时,读取文件"foo.bar"并将其内容链接到我的程序,以便我能够从内容中访问内容作为二进制数据码.
对于我想作为单个.exe文件分发的小型应用程序可能很有用.
GCC是否支持这样的事情?
一些框架(Qt,Windows,Gtk ...)提供了向二进制文件添加资源的功能.我想知道是否有可能在没有框架的情况下实现这一点,因为所有真正需要的是
如何使用gcc工具链实现这一目标?
我有一个C库,我构建为Linux的共享对象和带有MinGW32的Windows的DLL.API取决于几个数据文件(统计模型),我真的想用SO/DLL滚动,因此部署只是一个文件.
看起来我可以使用编译的"资源文件"为Windows实现这一点windres
,但后来我必须为Windows编写一堆资源处理代码,而我仍然坚持使用Linux上的文件.
有没有办法在Linux上实现相同的功能?
更好的是,有便携式解决方案吗?
这可能是一件非常简单的事情,但我是C++的新手,所以需要帮助.
我只想在我的C++头文件中声明一个数组,如:
int lettersArr[26];
Run Code Online (Sandbox Code Playgroud)
然后在cpp文件的函数中定义它,如:
lettersArr[26] = { letA, letB, letC, letD, letE, letF, letG, letH,
letI, letJ, letK, letL, letM, letN, letO, letP, letQ, letR, letS,
letT, letU, letV, letW, letX, letY, letZ };
Run Code Online (Sandbox Code Playgroud)
但这不起作用.
我的语法有错吗?这是正确的方法是什么?
非常感谢.
我有一个用C++编写的小型演示可执行文件,它只依赖于在运行之前加载的一个5kb PNG图像,用于我制作的像素文本.由于这个文件,我需要提供一个ZIP存档而不是只有一个可执行文件,这会在下载和"播放"之间产生足够的摩擦,我相信这会阻止一些人尝试它.
我的问题是,无论如何将PNG文件(以及任何其他文件)真正嵌入到可执行文件或源代码中,以便它是一个文件,并且可执行文件可以使用它吗?
我能够将PNG解析为字节流,因此不需要将其转换为像素数据.
提前致谢!(存在与此类似标题的其他问题,但他们和他们的答案似乎涉及更具体的问题,并且不是很有帮助)
编辑:编译器是Visual C++ 2010,这是在Windows上(虽然我想避免Windows特定的实用程序)
edit2:Alf的答案看起来像是最便携的方法,所以我很快写了一个函数来将PNG文件解析成TXT或头文件,可以读作unsigned char
数组.它在这种形式下似乎与PNG文件本身相同,但我的png加载器不接受该数组.从内存加载时,PNG解析器会接受(void * buffer, size_t length)
它是否重要.
代码,如果你想看,但如果你认为它们比这个方法更好,我仍会接受其他答案:
void compileImagePNGtoBinary(char * filename, char * output){
FILE * file = fopen(filename, "rb");
FILE * out = fopen(output, "w");
unsigned char buffer[32];
size_t count;
fprintf(out, "#pragma once \n\n static unsigned char TEXT_PNG_BYTES[] = { ");
while(!feof(file)){
count = fread(buffer, 1, 32, file);
for(int n = 0; n < count; ++n){
fprintf(out, "0x%02X, ", buffer[n]);
};
};
fprintf(out, "};"); …
Run Code Online (Sandbox Code Playgroud) 我有一个工作的链接器脚本.我想添加另一个数据部分,其内容直接从文件中提取(ld不应该解析它并提取部分等等).我怎样才能做到这一点?
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
SECTIONS
{
.text 0x100000 : {
*(.multiboot)
*(.text)
*(.code)
*(.rodata*)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
kernel_end = .;
roottask_start = .;
.data : {
HERE I WANT TO INCLUDE THE ENTIRE CONTENTS OF ANOTHER (BINARY) FILE
}
roottask_end = .;
}
Run Code Online (Sandbox Code Playgroud) 我需要对像素缓冲区做一些基本的文本渲染,我认为有一个用char索引的表,字母表示为二进制数组就足够了......有人知道这样的免费标题吗?
例:
char data[256][8][8];
void init()
{
data['a'] = {
{0,0,1,1,1,0,0,0},
{0,1,0,0,0,1,0,0},
{0,0,0,0,0,0,1,0},
{0,0,1,1,1,0,1,0},
{0,1,0,0,0,1,1,0},
{0,1,0,0,0,0,1,0},
{0,1,0,0,0,1,1,0},
{0,0,1,1,1,0,1,0},
};
}
Run Code Online (Sandbox Code Playgroud)
我可以继续使用剩余的字母表,但后来我不需要问......但是这给了我一个想法!如果没有可用的位图字体的免费标题,每个答案都可以实现一个字母,我可以在这里组装整个文件^ _ ^
有几个问题涉及这个问题的某些方面,但似乎都没有完全回答它.整个问题可归纳如下:
我的特定用例是一个解释器,我想让用户能够用解释器二进制文件和他提供的代码生成一个单独的文件可执行文件(解释器二进制文件是必须用它修补的可执行文件).用户提供的代码作为二进制数据).
类似的情况是自解压存档,其中程序(存档实用程序,如zip)能够构造这样的可执行文件,其中包含预构建的解压缩程序(已编译的可执行文件)和用户提供的数据(内容)存档).显然,此过程中不涉及编译器或链接器(感谢,Mathias为注释并指出7-zip).
使用现有问题,解决方案的特定路径如下所示:
将数据附加到exe - 这涉及向任意exes添加任意数据的方面,而不涉及如何实际访问它(基本上简单的追加通常有效,对于Unix的ELF格式也是如此).
在没有/ proc/self/exe的情况下查找当前可执行文件的路径 - 与上述相同,这将允许获取用于打开exe的文件名,以访问添加的数据.还有更多这类问题,但是它们都没有特别关注获得适合于实际将二进制文件作为文件打开的目的的路径问题(单独的目标可能(?)更容易实现 - 真的你不要甚至不需要路径,只是打开阅读的二进制文件.
除了填充二进制文件并打开文件以进行读取之外,还可能存在其他可能更优雅的方法.例如,可执行文件可以使得以后使用任意大小的数据对其进行修补变得相当简单,因此它它出现在某个正确的数据段"内"?(我真的找不到任何东西,对于固定大小的数据,它应该是微不足道的,尽管除非可执行文件有一些哈希值)
这可以做得相当好,与标准C的偏差尽可能小吗?甚至或多或少的跨平台?(至少从维护的角度来看)请注意,如果执行二进制数据添加的程序不依赖于编译器工具(用户可能没有),那么首选,但是需要这些工具的解决方案也可能有用. .
请注意已经编译的可执行标准(上面列表中的第一点),这需要一种完全不同于C/C++与GCC之类的问题中描述的解决方案:静态地将资源文件添加到可执行文件库或SDL嵌入图像内部的程序可执行文件中,要求嵌入数据编译时.
补充说明:
上面列出并在一些注释中提出的明显方法的问题,即只是附加到二进制文件并使用它,如下所示:
我正在开发一个没有文件系统的嵌入式系统,我需要执行从通过命令(如参数)指定的文件或直接从标准输入指定的文件中获取输入数据的程序。
我知道可以使用以下答案中的方法用二进制文件烘焙文件数据:C/C++ with GCC: Statically add resources file toexecutable/library但目前我需要重写所有程序来访问数据以一种新的方式。
例如,是否可以烘焙一个文本文件,并在运行程序时使用指向 stdin 的假文件指针来访问它?
有没有预处理器技巧可以让我将文件作为字符串“包含”在标题中?
像这样:
a.txt
lorem ipsum dolorem
sit amet
Run Code Online (Sandbox Code Playgroud)
而“魔术”包含调用与此类似:
header.h
MAGICINCLUDE(a.txt, atxt)
Run Code Online (Sandbox Code Playgroud)
结果,预处理器会欺骗,上面的行与此等效:
const char* atxt = "lorem ipsum dolorem\n\
sit amet";
Run Code Online (Sandbox Code Playgroud)
不应使用任何外部工具,而应使用预处理器:我试图摆脱执行此操作的python脚本。
我们有一大堆C++项目(GCC,Linux,主要是静态库),它们之间有许多依赖关系.然后我们使用这些库编译可执行文件并在前端部署二进制文件.能够识别二进制文件是非常有用的.理想情况下,我们希望拥有一个小脚本,可直接从二进制文件中检索以下信息:
$ident binary
$binary : Product=PRODUCT_NAME;Version=0.0.1;Build=xxx;User=xxx...
$ dependency: Product=PRODUCT_NAME1;Version=0.1.1;Build=xxx;User=xxx...
$ dependency: Product=PRODUCT_NAME2;Version=1.0.1;Build=xxx;User=xxx...
Run Code Online (Sandbox Code Playgroud)
所以它应该显示二进制本身及其所有依赖项的所有信息.
目前我们的方法是:
在为每个产品编译期间,我们生成Manifest.h和Manifest.cpp,然后将Manifest.o注入二进制文件
ident脚本解析目标二进制文件,在那里找到生成的东西并打印此信息
然而,对于不同版本的gcc,这种方法并不总是可靠的.我想问SO社区 - 有没有更好的方法来解决这个问题?
谢谢你的建议
我基本上想看看是否有可能将Python代码编译成C++程序,以便生成单个二进制文件,然后使用C++代码中的函数调用(编译的)python代码.
背景:我有一个C++代码可以完成一些工作并生成我想要绘制的数据.然后,我使用SciPy编写了一个单独的Python脚本,该脚本读取输出数据,处理它并将其绘制到文件中.一切都按原样运作.
基本上,我想象的是:
void plotstuff() {
my_python_func(); // This is the python script compiled into the c++ binary
}
Run Code Online (Sandbox Code Playgroud)
我不需要在python代码和C++代码之间传递任何东西,除了确保它在同一目录中执行.如果我可以传递字符串参数,它可能会使事情变得更容易,但再次 - 不是必需的.
这可以实现吗?或者它通常是一个坏主意,我应该坚持让我的C++和python分开?