GNU/Linux >> Tutoriales Linux >  >> Linux

C/C++ con GCC:agrega estáticamente archivos de recursos al ejecutable/biblioteca

Con imagemagick:

convert file.png data.h

Da algo como:

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

....

Para compatibilidad con otro código, puede usar fmemopen para obtener un FILE * "regular" objeto, o alternativamente std::stringstream para hacer un iostream . std::stringstream Sin embargo, no es bueno para esto y, por supuesto, puede usar un puntero en cualquier lugar donde pueda usar un iterador.

Si está utilizando esto con automake, no olvide configurar BUILT_SOURCES de manera adecuada.

Lo bueno de hacerlo de esta manera es:

  1. Obtienes el texto, por lo que puede estar en el control de versiones y parches con sensatez
  2. Es portátil y está bien definido en todas las plataformas

Puede incrustar archivos binarios en el ejecutable usando ld enlazador. Por ejemplo, si tiene el archivo foo.bar luego puede incrustarlo en el ejecutable agregando los siguientes comandos a ld

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

Si está invocando ld hasta gcc entonces deberá agregar -Wl

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

Aquí --format=binary le dice al enlazador que el siguiente archivo es binario y --format=default vuelve al formato de entrada predeterminado (esto es útil si va a especificar otros archivos de entrada después de foo.bar ).

Luego puede acceder al contenido de su archivo desde el código:

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

También hay un símbolo llamado "_binary_foo_bar_size" . Creo que es del tipo uintptr_t pero no lo comprobé.


Actualizar He llegado a preferir el montaje de control de John Ripley .incbin ofertas de soluciones basadas y ahora use una variante de eso.

He usado objcopy (GNU binutils) para vincular los datos binarios de un archivo foo-data.bin a la sección de datos del ejecutable:

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

Esto te da un foo-data.o archivo de objeto que puede vincular a su ejecutable. La interfaz C se parece a

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

para que puedas hacer cosas como

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

o

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 su arquitectura de destino tiene restricciones especiales en cuanto a dónde se almacenan los datos constantes y variables, o si desea almacenar esos datos en el .text segmento para que encaje en el mismo tipo de memoria que el código de su programa, puede jugar con el objcopy parámetros un poco más.


Linux
  1. Encuentra archivos y directorios en Linux con el comando de búsqueda

  2. Cómo agregar números de línea a archivos de texto en Linux

  3. ¿Cuándo no lo son los archivos ejecutables?

  4. (C/C++) ¿Cómo generar un archivo ejecutable que pueda ejecutarse tanto en Windows como en Linux?

  5. Vincular una biblioteca compartida con otra biblioteca compartida en Linux

Linux:Cómo compartir archivos en una red local con guau

Consejos de Vim:edite archivos remotos con Vim en Linux

Encuentra archivos perdidos con Scalpel

Cómo copiar archivos con una extensión de archivo específica recursivamente

Manera fácil de fusionar archivos con el comando Cat

Los archivos zip se expanden con barras invertidas en Linux, sin subdirectorios