GNU/Linux >> LINUX-Kenntnisse >  >> Linux

C/C++ mit GCC:Ressourcendateien statisch zur ausführbaren Datei/Bibliothek hinzufügen

Mit imagemagick:

convert file.png data.h

Ergibt etwas wie:

/*
  data.h (PNM).
*/
static unsigned char
  MagickImage[] =
  {
    0x50, 0x36, 0x0A, 0x23, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 
    0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4D, 0x50, 0x0A, 0x32, 0x37, 
    0x37, 0x20, 0x31, 0x36, 0x32, 0x0A, 0x32, 0x35, 0x35, 0x0A, 0xFF, 0xFF, 
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 

....

Für die Kompatibilität mit anderem Code können Sie dann entweder fmemopen verwenden um eine "normale" FILE * zu erhalten Objekt oder alternativ std::stringstream um eine iostream zu machen . std::stringstream ist dafür aber nicht gut und Sie können natürlich überall dort, wo Sie einen Iterator verwenden können, einfach einen Zeiger verwenden.

Wenn Sie dies mit automake verwenden, vergessen Sie nicht, BUILT_SOURCES entsprechend einzustellen.

Das Schöne daran, es so zu machen, ist:

  1. Sie bekommen Text raus, damit er in der Versionskontrolle und Patches sinnvoll sein kann
  2. Es ist portabel und auf jeder Plattform gut definiert

Mit ld können Sie Binärdateien in ausführbare Dateien einbetten Linker. Zum Beispiel, wenn Sie die Datei foo.bar haben dann können Sie es in eine ausführbare Datei einbetten, indem Sie die folgenden Befehle zu ld hinzufügen

--format=binary foo.bar --format=default

Wenn Sie ld aufrufen bis gcc dann müssen Sie -Wl hinzufügen

-Wl,--format=binary -Wl,foo.bar -Wl,--format=default

Hier --format=binary teilt dem Linker mit, dass die folgende Datei binär ist und --format=default schaltet zurück zum Standard-Eingabeformat (dies ist nützlich, wenn Sie nach foo.bar andere Eingabedateien angeben ).

Dann können Sie mit folgendem Code auf den Inhalt Ihrer Datei zugreifen:

extern uint8_t data[]     asm("_binary_foo_bar_start");
extern uint8_t data_end[] asm("_binary_foo_bar_end");

Es gibt auch ein Symbol namens "_binary_foo_bar_size" . Ich denke, es ist vom Typ uintptr_t aber ich habe es nicht überprüft.


Aktualisieren Ich bevorzuge inzwischen die Steuerung von John Ripleys Assembly .incbin basierende Lösungsangebote und nutzen Sie nun eine Variante davon.

Ich habe objcopy (GNU binutils) verwendet, um die Binärdaten aus einer Datei foo-data.bin in den Datenabschnitt der ausführbaren Datei zu verlinken:

objcopy -B i386 -I binary -O elf32-i386 foo-data.bin foo-data.o

Dies gibt Ihnen einen foo-data.o Objektdatei, die Sie in Ihre ausführbare Datei einbinden können. Die C-Schnittstelle sieht in etwa so aus

/** created from binary via objcopy */
extern uint8_t foo_data[]      asm("_binary_foo_data_bin_start");
extern uint8_t foo_data_size[] asm("_binary_foo_data_bin_size");
extern uint8_t foo_data_end[]  asm("_binary_foo_data_bin_end");

damit Sie Dinge tun können wie

for (uint8_t *byte=foo_data; byte<foo_data_end; ++byte) {
    transmit_single_byte(*byte);
}

oder

size_t foo_size = (size_t)((void *)foo_data_size);
void  *foo_copy = malloc(foo_size);
assert(foo_copy);
memcpy(foo_copy, foo_data, foo_size);

Wenn Ihre Zielarchitektur spezielle Einschränkungen hinsichtlich des Speicherorts konstanter und variabler Daten hat oder Sie diese Daten in .text speichern möchten Segment, damit es in denselben Speichertyp wie Ihr Programmcode passt, können Sie mit dem objcopy spielen Parameter etwas mehr.


Linux
  1. Wann sind es ausführbare Dateien nicht?

  2. Laden Sie Dateien als ASCII oder binär mit FTP hoch

  3. Howto:C-Programmierung mit temporären Dateien unter Linux

  4. (C/C++) Wie generiert man eine ausführbare Datei, die sowohl unter Windows als auch unter Linux ausgeführt werden kann?

  5. So fügen Sie eine .so-Datei zum java.library.path in Linux hinzu

Linux:So teilen Sie Dateien in einem lokalen Netzwerk mit woof

Vim-Tipps – Bearbeiten Sie Remote-Dateien mit Vim unter Linux

Finden Sie verlorene Dateien mit Scalpel

So kopieren Sie Dateien mit einer bestimmten Dateierweiterung rekursiv

Einfache Möglichkeit, Dateien mit dem Cat-Befehl zusammenzuführen

Zip-Dateien werden unter Linux mit Backslashes erweitert, keine Unterverzeichnisse