Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有没有标准的方法将资源嵌入Linux可执行映像?_C++_Linux_Embedded Resource - Fatal编程技术网

C++ 有没有标准的方法将资源嵌入Linux可执行映像?

C++ 有没有标准的方法将资源嵌入Linux可执行映像?,c++,linux,embedded-resource,C++,Linux,Embedded Resource,通过Windows API将二进制资源嵌入PE映像(EXE、DLL)非常容易(请参阅) Linux中是否有类似的标准API? 或者是某种事实上的资源嵌入方法 目标是将一些静态二进制和/或文本数据嵌入到可执行文件中,例如图片、HTML等。。那么,程序二进制分发就像制作一个文件副本一样简单?(假设所有库依赖项都正常) 更新: 根据bdk的建议,我尝试了中描述的解决方案,它对我有效。然而,有一些值得提及的问题:我的项目(在代码::块)由许多C++文件组成,并将二进制数据添加到相应的对象文件中,使它们变

通过Windows API将二进制资源嵌入PE映像(EXE、DLL)非常容易(请参阅)

Linux中是否有类似的标准API?

或者是某种事实上的资源嵌入方法

目标是将一些静态二进制和/或文本数据嵌入到可执行文件中,例如图片、HTML等。。那么,程序二进制分发就像制作一个文件副本一样简单?(假设所有库依赖项都正常)

更新:

根据bdk的建议,我尝试了中描述的解决方案,它对我有效。然而,有一些值得提及的问题:我的项目(在代码::块)由许多C++文件组成,并将二进制数据添加到相应的对象文件中,使它们变得无用,破坏了构建-<代码> ObjDIP-X/CODE >,这表明大多数符号已经在嵌入之后消失(我没有找到如何修复它)。为了解决这个问题,我在项目中添加了一个空的dummy.cpp文件,唯一的目的是提供一个可使用的对象文件,并为该文件编写了以下自定义构建步骤,该步骤很好地完成了工作(示例使用Code::Blocks宏):

$compiler$options$includes-c$file-o$object
ld-Ur-b二进制-o$对象
当然可以。试试类似的东西。将二进制数据转换为C++ char数组,然后将其嵌入到代码中作为常量变量。

Objope-添加部分允许您在ELF可执行文件中添加任意文件作为节。(objcopy手册页)。然而,这只是解决方案的一半,因为除了使用ELF库加载和解析ELF二进制文件之外,我还没有找到从C程序内部访问这些数据的方法

编辑其他信息:

如果您有一个名为MyProgram的编译程序和一个要嵌入MyProgram的资源文件MyResource.dat,则可以像下面这样使用objcopy命令:

objcopy MyProgram --add-section MyResource=MyResource.dat
现在,如果您使用命令查看您的程序 objdump-x MyProgram

您将看到一个名为MyResource的部分,其中包含MyResource.dat的内容。该文件现在嵌入到可执行文件中

现在的诀窍是如何从程序内部访问数据。我的直觉告诉我,加载程序应该把文件放在内存中的某个地方,你应该能够得到一个指向它的指针,但是我不知道如何简单地做到这一点。理想情况下,我希望能够dlopen我的EXEXUTABLE和dlsym的部分,但这不起作用,因为它是一个部分,而不是一个符号

我所知道的从程序内部访问该部分的唯一替代方法是使用libelf库或类似的东西,这有点像使用大锤敲打钉子。您可以在应用程序中使用它将自身作为ELF资源加载并检索节。文档很少,但这里有一个例子

我希望有人能提供一种更简单的方法来访问--添加部分的数据

编辑2在我的研究中,我遇到了这个问题:

它应该适用于gcc和mingw,并展示了一种使用ld而不是objcopy来添加数据并能够将其作为符号访问的方法。看起来很有前途

怎么样

它将从一个目录中创建一个tar存档,在这个目录中,您的所有程序、资源和文件都将被保存到一个可执行的shell文件中。 当用户运行可执行文件时,它将提取文件并运行任意命令(可能是程序的主可执行文件)。
有一个缺点,每次用户启动可执行文件时,在启动真正的程序之前,都需要先加载/提取文件。

将自己变成一个汇编程序文件,blob.s:

    .global blob
    .global blob_size
    .section .rodata
blob:
    .incbin "blob.bin"
1:
blob_size:
    .int 1b - blob
使用gcc-cflob.S-oblob.o编译 现在可以通过以下方式从C程序中访问blob:

extern uint8_t blob[];
extern int blob_size;

使用bin2c转换器通常可以正常工作,但如果blob较大,incbin解决方案会更快,并且使用更少的内存(编译时)

感谢链接,我以前见过这个解决方案(它用于在Motif中表示图标)。但我不喜欢它——它在我的构建过程中引入了
perl
,更糟糕的是,它在代码中引入了一些hexmare。不过,这是一个解决办法,所以+1@Andrey,坦率地说,如果您真的愿意,您可以不使用
perl
,甚至只使用
bash
,轻松地实现这样的脚本。过来看。Re hexmare-忽略它,就像忽略二进制数据文件内容一样。只需将它放在一个单独的
.h
文件中,并将脚本添加到构建过程中,就完成了。基本上,MSVC也是这样使用他们的资源的。我使用
xxd-I
来实现这一点。您不能将节添加到.o文件中,然后创建重新定位符号吗。这就可以允许从另一个C或C++文件链接到这里,这似乎非常接近我想要的,请您详细阐述一下。还有什么
ELF库
,它能保证在现代Linux上使用吗?也许你可以添加一些参考资料?你太棒了!非常感谢您通过改进您的答案并添加所有这些重要的细节,完成了额外的工作。“编辑2”中的解决方案对我有效。您可以将选项
--set section flags MyResource=alloc,load--change section address MyResource=
添加到objcopy命令中,以使链接器以固定地址加载MyResource节。找出一个合理的地址是很棘手的。非常好的方法。非常感谢。你知道这在GCC支持的各种平台上的可移植性吗?它应该是可移植的,这是linux内核用来向映像添加initramfs文件系统的方式。这应该是公认的答案。我想更明确的一点是,应该存在一个名为“blob.bin”的文件,它的内容是嵌入的。@noloader他问的关于Linux的问题,.exe是用于Windows的。你应该多加注意:)@sashaalm-The
extern uint8_t blob[];
extern int blob_size;