GNU/Linux >> Tutoriels Linux >  >> Linux

C/C++ avec GCC :ajouter statiquement des fichiers de ressources à l'exécutable/à la bibliothèque

Avec imagemagick :

convert file.png data.h

Donne quelque chose comme :

/*
  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, 

....

Pour la compatibilité avec d'autres codes, vous pouvez alors utiliser soit fmemopen pour obtenir un FILE * "normal" objet, ou alternativement std::stringstream faire un iostream . std::stringstream n'est pas idéal pour cela cependant et vous pouvez bien sûr simplement utiliser un pointeur partout où vous pouvez utiliser un itérateur.

Si vous l'utilisez avec automake, n'oubliez pas de définir BUILT_SOURCES de manière appropriée.

La bonne chose à faire de cette façon est :

  1. Vous obtenez du texte, de sorte qu'il peut être dans le contrôle de version et les correctifs judicieusement
  2. Il est portable et bien défini sur chaque plate-forme

Vous pouvez intégrer des fichiers binaires dans un exécutable en utilisant ld linker.Par exemple, si vous avez le fichier foo.bar alors vous pouvez l'intégrer dans un exécutable en ajoutant les commandes suivantes à ld

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

Si vous appelez ld jusqu'à gcc alors vous devrez ajouter -Wl

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

Ici --format=binary indique à l'éditeur de liens que le fichier suivant est binaire et --format=default revient au format d'entrée par défaut (ceci est utile si vous spécifiez d'autres fichiers d'entrée après foo.bar ).

Ensuite, vous pouvez accéder au contenu de votre fichier à partir du code :

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

Il existe également un symbole nommé "_binary_foo_bar_size" . Je pense qu'il est de type uintptr_t mais je n'ai pas vérifié.


Mettre à jour J'ai appris à préférer le contrôle de l'assemblage de John Ripley .incbin offres de solutions basées sur des offres et maintenant utiliser une variante sur cela.

J'ai utilisé objcopy (GNU binutils) pour lier les données binaires d'un fichier foo-data.bin dans la section data de l'exécutable :

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

Cela vous donne un foo-data.o fichier objet que vous pouvez lier dans votre exécutable. L'interface C ressemble à quelque chose comme

/** 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");

pour que vous puissiez faire des choses comme

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

ou

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);

Si votre architecture cible a des contraintes particulières quant à l'endroit où les données constantes et variables sont stockées, ou si vous souhaitez stocker ces données dans le .text segment pour le faire tenir dans le même type de mémoire que votre code de programme, vous pouvez jouer avec le objcopy paramètres un peu plus.


Linux
  1. Lorsque les fichiers exécutables ne le sont pas ?

  2. Télécharger des fichiers au format ASCII ou binaire avec FTP

  3. Howto :Programmation en C avec des fichiers temporaires sous Linux

  4. (C/C++) Comment générer un fichier exécutable pouvant fonctionner à la fois sous Windows et Linux ?

  5. Comment ajouter un fichier .so au java.library.path sous Linux

Linux :Comment partager des fichiers sur un réseau local avec woof

Comment ajouter des numéros de ligne aux fichiers texte sous Linux

Conseils Vim - Modifier des fichiers distants avec Vim sous Linux

Retrouver les fichiers perdus avec Scalpel

Comment copier des fichiers avec une extension de fichier spécifique de manière récursive

Un moyen facile de fusionner des fichiers avec la commande Cat