1

Pouet,

Je voudrais savoir comment intégrer des ressources à un binaire, pour éviter de le ballader avec plein de petits fichiers textes/png/whatever à côté.

Quand j'utilise Qt, je peux faire ça. Mais quand j'utilise GCC en standalone, ou encore MSVC++, je ne sais pas comment faire pour transformer des fichiers externes en données internes, et ensuite y accéder.

Vers où dois-je me pencher svp ?

2

Ça manque, l'équivalent de incbin en C, hein ? tongue

Je vois au moins 3 moyens de faire ça :

- utiliser un convertisseur fichier binaire -> source C, qui va te créer un .c de ce genre :
const uint8_t mon_beau_fichier[] = {0x0F, 0x01, 0xC0, ..., 0x42}; qu'il suffira de compiler et linker avec le reste.
Le principe est crade, mais c'est le plus simple et c'est portable (et une fois compilé, on ne voit pas la différence cheeky)

- même principe, mais en utilisant un convertisseur fichier binaire -> fichier .o contenant un symbole avec tes données. C'est plus casse-pieds à faire marcher, mais c'est faisable, j'ai vaguement le souvenir qu'on peut le faire avec binutils pour GCC (pour VC++ je sais pas).

- pour Windows uniquement : utiliser des ressources. En gros, ce sont des données intégrées à l'exécutable, pour lesquelles tu peux définir un type et un nom. Les fonctions pour les charger en mémoire sont déjà faites (et quelques fonctions Windows te permettent même de passer directement un handle de ressource au lieu de t'occuper du chargement toi-même).

Après tu peux empiler les abstractions, rien ne t'empêche de faire un système de fichiers virtuels encapsulé dans un unique bloc de données (et donc de pouvoir accéder à tes données par leur nom, comme si c'était des fichiers ordinaires). Pas mal de jeux font ça par exemple.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

3

Pour les applications Windows, on utilise le format de ressources binaires de Win32 qui permet de faire ça.
Ces fichiers ont l'extension .res. Ils peuvent être générés directement par certains outils, ou compilés par le compilateur de ressources (rc.exe) à partir d'un fichier texte .rc.
Ensuite, tu fournis ce fichier (.res) au linker (ou compilateur) et il intègre les ressources dans l'exécutable. Le paramètre à fournir au linker (ou compilateur) va dépendre du compilateur. (Ça se trouve assez facilement pour VC++, mais pour GCC (MinGW) j'ai pas trouvé la doc)
Après, l'utilisation des ressources se fait via les API Win32. FindResource, LoadResource, LoadIcon, etc.

Mais en procédant ainsi, ton application n'est pas portable.
Le point de la portabilité n'est pas difficile à régler, il te suffit de créer des classes et/ou fonctions pour gérer les ressources de manière indépendante du système… Les méthodes seront implémentées différemment selon la plateforme cible, et le tour est joué.
Seulement, à ma connaissance, il n'existe pas de procédé totalement équivalent sur les plateformes autres que Windows. (C'est plutôt là que'est le problème. En gros, tu pourras le faire, mais seulement sous Windows).
Sous Mac OS X, les ressources ne sont pas inclues dans le binaire, mais sont packagées avec, et il existe des API prévus spécialement pour gérer l'accès aux ressources, qui restent des fichiers à part. (NB: C'est pas forcément très efficace au point de vue économie de l'espace disque)
Sous Linux, heu, je crois que tu dois te démerder toi même. (Ou utiliser un truc qui gère ça pour toi)

Mais le plus gros problème sans doute, c'est qu'en intégrant les ressources à l'exécutable, ça veut dire qu'elles vont toujours être mappées en mémoire, et probablement consommer de la RAM même lorsqu'elles ne sont pas utilisées.
Selon le nombre et la taille de tes ressources, il est peut-être préférable d'utiliser un format d'archive comme .zip, te permettant de réduire le nombre de fichiers visible (un exécutable et une archive de données), mais te laissant la possibilité de gérer tes ressources comme tu veux. En plus tu as le bénéfice potentiel de la compression, donc ton application peut se trouver moins volumineuse que par d'autres moyens... wink

(cross tongue)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

4

Ok. Merci bien pour les infos. Et quel serait votre choix, à vous, pour les données graphiques d'un jeu ? L'archive à côté du binaire ?

5

Ça me paraît être une bonne solution, oui, et pas mal d'applis le font.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

6

Ben purée : http://zlib.net/manual.html
Alors qu'il me faut juste une fonction < uncompress ("mes_putains_de_sprites", "."); >
Paye ton usine à gaz, et faut encore comprendre comment ça marche ce truc :/

7

personnellement soit j'utilisais un fichier rar 2.x avec toute mes données à l'intérieur (bmp, mod, ...) que je convertissais ensuite en .h (ensuite l'exe est reconnu par winrar comme une archive propre contenant les ressources)

soit, j’intégrais chaque image/son directement depuis un .h propre et je passais l’exécutable de sortie sous upx
et la le mec il le pécho par le bras et il lui dit '

8

./6 > Je crois avoir lu quelque part sur yAronet que zlib inclut minizip dans ses sources. Ça devrait plus correspondre à ce dont tu as besoin. (Cela dit, je ne m'en suis jamais servi)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

9

C'est le cas (j'ai vu ça en lisant la doc citée par Folco tout à l'heure).
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

10

http://tigcc.ticalc.org/doc/default.html#import_binary ← Cette macro devrait fonctionner avec n'importe quel target GCC basé sur GNU as (mais certains demandent un underscore devant le nom de symbole, et en C++ tu dois utiliser extern "C" pour importer la variable définie en assembleur).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

11

Ok, merci bien. smile

12

Tiens, c'est amusant que GNU AS implémente ça.
Ceci dit, la méthode la plus portable reste quand même la plus crade tongue
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

13

Zerosquare (./12) :
Tiens, c'est amusant que GNU AS implémente ça.

Ça a été rajouté à un moment, les GNU as des toutes premières versions de TIGCC ne géraient pas encore .incbin, maintenant ça y est (même dans des versions de GNU as considérées "antiques" à l'échelle de GNU/Linux).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité