46 votes

Puis-je lier un fichier brut à mon exécutable?

Certains frameworks (Qt, Windows, Gtk ...) offrent des fonctionnalités pour ajouter des ressources à vos fichiers binaires. Je me demande s’il serait possible d’y parvenir sans le cadre, puisqu’il suffit de

  1. un symbole pour contenir l'adresse de la ressource dans le binaire (segment de données)
  2. un symbole pour représenter la longueur de la ressource
  3. la ressource elle-même

Comment cela peut-il être réalisé avec la chaîne d’outils gcc?

48voto

nos Points 102226

Vous pourriez faire ceci:

 objcopy --input binary \
        --output elf32-i386 \
        --binary-architecture i386 my_file.xml myfile.o
 

Cela produit un fichier objet que vous pouvez lier à votre exécutable. Ce fichier contiendra ces symboles que vous devrez déclarer dans votre code C pour pouvoir les utiliser

 00000550 D _binary_my_file_xml_end
00000550 A _binary_my_file_xml_size 
00000000 D _binary_my_file_xml_start
 

31voto

À la base, l'équivalent est un char tableau d'octets.

Sur Linux, vous pouvez utiliser xxd -i <file> de "compiler" les fichiers dans char tableaux, puis lier les tableaux dans votre binaire et l'utilisation de la constituante octets cependant vous s'il vous plaît.

Voici un exemple tiré de ma propre code de l' makefile, qui crée un "fichier de ressources" appelés templates.h contenant un tas de char tableaux représentant des modèles HTML:

templates.h:
    @echo "#ifndef REDACTED_TEMPLATES_H" > templates.h
    @echo "#define REDACTED_TEMPLATES_H" >> templates.h
    @echo "// Auto-generated file! Do not modify!" >> templates.h
    @echo "// NB: arrays are not null-terminated" >> templates.h
    @echo "// (anonymous namespace used to force internal linkage)" >> templates.h
    @echo "namespace {" >> templates.h
    @echo "namespace templates {" >> templates.h
    @cd templates;\
    for i in * ;\
    do \
        echo "Compiling $$i...";\
        xxd -i $$i | sed -e 's/ =/ __attribute__((unused)) =/' >> ../templates.h;\
    done;\
    cd ..
    @echo "}" >> templates.h
    @echo "}" >> templates.h
    @echo "#endif" >> templates.h

(voir aussi: Comment pouvons-je appliquer par programme `__attribute__ ((non))` auto généré des objets?)

Le résultat ressemble un peu à:

#ifndef REDACTED_TEMPLATES_H
#define REDACTED_TEMPLATES_H
// Auto-generated file! Do not modify!
// NB: arrays are not null-terminated
// (anonymous namespace used to force internal linkage)
namespace {
namespace templates {
unsigned char alert_email_finished_events_html[] __attribute__((unused)) = {
  0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73,
  0x3d, 0x22, 0x6e, 0x6f, 0x64, 0x65, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2d,
[..]
  0x7d, 0x7d, 0x0d, 0x0a, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e,
  0x0d, 0x0a
};
unsigned int alert_email_finished_events_html_len __attribute__((unused)) = 290;
unsigned char alert_email_finished_events_list_html[] __attribute__((unused)) = {
  0x3c, 0x74, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73,
  0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x70, 0x72, 0x65, 0x76,
[..]
  0x73, 0x74, 0x7d, 0x7d, 0x0d, 0x0a
};
unsigned int alert_email_finished_events_list_html_len __attribute__((unused)) = 42;
}
}
#endif

Notez que cet exemple particulier est optimal lors de l'utilisation de la ressource dans une seule Unité de Traduction, mais l'approche générale peut être adapté à vos besoins.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X