How to embed a file into an executable file?

Viewed 7621

I have two problems, the first has been solved.

Current problem
If I embed a file that requires a library to load it, such as a jpeg image or a mp3 music, I will need to use the file as input to the library. However, each library is different and uses a way to get a file as input, the input may be the file name or a FILE* pointer (from libc's file interface).

I would like to know how to access an embedded file with a name. It will be inefficient if I create a temporary file, is there another way? Can I map a file name to memory? My platforms are Windows and Linux.

If show_file(const char* name) is a function from a library, I will need a string to open the file.
I have seen these questions:
How to get file descriptor of buffer in memory?
Getting Filename from file descriptor in C

and the following code is my solution. Is it a good solution? Is it inefficient?

# 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]);
}

The other problem (solved)
I tried to embed a file on Linux, with GCC, and it worked. However, I tried to do the same thing on Windows, with Mingw, and it did not compile.

The code is:

# 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");
}

The compilation commands are:

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

On Windows, I get the following compiler error:

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

I tried to replace elf32-i386 with i386-pc-mingw32, but I still get the same error.

5 Answers
Related