c++ - 如何将文件嵌入到可执行文件中?

标签 c++ c file binary executable

我有两个问题,第一个已经解决了。

当前问题
如果我嵌入了一个需要库才能加载的文件,例如 jpeg 图像或 mp3 音乐,我将需要使用该文件作为库的输入。但是,每个库都不同,并使用一种方式来获取文件作为输入,输入可能是文件名或 FILE* 指针(来自 libc 的文件接口(interface))。

我想知道如何访问带有名称的嵌入文件。如果我创建一个临时文件会效率低下,还有其他方法吗?我可以将文件名映射到内存吗?我的平台是 Windows 和 Linux。

如果 show_file(const char* name) 是库中的函数,我需要一个字符串来打开文件。
我看过这些问题:
How to get file descriptor of buffer in memory?
Getting Filename from file descriptor in C

下面的代码是我的解决方案。这是一个很好的解决方案吗?效率低吗?

# include <stdio.h>
# include <unistd.h>

extern char _binary_data_txt_start;
extern const void* _binary_data_txt_size;
const size_t len = (size_t)&_binary_data_txt_size;

void show_file(const char* name){
    FILE* file = fopen(name, "r");
    if (file == NULL){
        printf("Error (show_file): %s\n", name);
        return;
    }

    while (true){
        char ch = fgetc(file);
        if (feof(file) )
            break;
        putchar( ch );
    }
    printf("\n");

    fclose(file);
}

int main(){

    int fpipe[2];
    pipe(fpipe);

    if( !fork() ){
        for( int buffsize = len, done = 0; buffsize>done; ){
            done += write( fpipe[1], &_binary_data_txt_start + done, buffsize-done );
        }
        _exit(0);
    }

    close(fpipe[1]);
    char name[200];
    sprintf(name, "/proc/self/fd/%d", fpipe[0] );

    show_file(name);

    close(fpipe[0]);
}

另一个问题(已解决)
我尝试使用 GCC 在 Linux 上嵌入一个文件,并且成功了。但是,我尝试在 Windows 上使用 Mingw 做同样的事情,但它没有编译。

代码是:

# include <stdio.h>

extern char _binary_data_txt_start;
extern char _binary_data_txt_end;

int main(){
    for (char* my_file = &_binary_data_txt_start; my_file <= &_binary_data_txt_end; my_file++)
        putchar(*my_file);
    printf("\n");
}

编译命令为:

objcopy --input-target binary --output-target elf32-i386 --binary-architecture i386 data.txt data.o
g++ main.cpp data.o -o test.exe

在 Windows 上,我收到以下编译器错误:

undefined reference to `_binary_data_txt_start'
undefined reference to `_binary_data_txt_end'

我尝试将 elf32-i386 替换为 i386-pc-mingw32,但仍然遇到同样的错误。

最佳答案

我认为要使此功能与 MinGW 一起使用,您需要从 .c 文件中的名称中删除前导下划线。见 Embedding binary blobs using gcc mingw了解一些细节。

看看使用以下是否有帮助:

extern char binary_data_txt_start;
extern char binary_data_txt_end;

如果您需要相同的源代码来为 Linux 或 MinGW 构建工作,您可能需要使用预处理器在不同的环境中使用正确的名称。

关于c++ - 如何将文件嵌入到可执行文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6785214/

相关文章:

c - printf 添加数字

c - 当我在 Eclipse Indigo CDT 中运行代码时输出错误

java - 列出目录中的文件时出错

C++ 结构数组的分配

c++ - C++错误“左操作数必须为l值”

c - 为什么这个结构文字在 VS2013 中通过地址而不是 gcc/clang 传递时被破坏?

python - 类文件对象的 `write` 方法返回什么?

c - 指向另一个结构中的一个结构的指针,从文件中写入和读取它会产生 SegFault

c++ - 使用 GStreamer 和 multiudpsink 设置不同的 RTP SSRC

c++ - 我的程序正在通过 cin.get 从之前的输入获取\n