Question

Est-il possible de construire des ressources dans une bibliothèque statique et les réutiliser en liant simplement avec la bibliothèque?

Je pense surtout sur le cas où vous appelez une fonction dans la bibliothèque qui à son tour accède à des ressources.

Était-ce utile?

La solution

Il peut être fait, mais il est très douloureux. Vous ne pouvez pas le faire en reliant simplement avec la bibliothèque statique

Considérez ceci: les ressources sont intégrées dans un fichier EXE ou DLL. Quand un code dans les appels de bibliothèque statiques (par exemple) LoadIcon, il va obtenir les ressources de la DLL ou EXE qu'il est lié avec.

Alors, si votre bibliothèque statique nécessite des ressources soient disponibles, vous avez deux options:

  1. Vous pouvez avoir la bibliothèque les construire à la volée, puis utilisez (par exemple) CreateDialogIndirect. Voir Raymond « Construire un modèle de dialogue à l'exécution » .
  2. Vous pouvez les intégrés dans la bibliothèque comme de simples tableaux (à savoir) char my_dialog_resource[] = { .... };, puis utilisez (par exemple) CreateDialogIndirect. Vous aurez probablement besoin de trouver (ou écrire) un utilitaire qui convertit les fichiers .RES à .CPP fichiers.
  3. Vous pouvez envoyer le fichier LIB avec un script de ressources (fichier .RC) et le fichier d'en-tête correspondant. Vous les #include alors comme pertinents. Vous aurez besoin de réserver une plage d'ID de ressources pour la LIB à utiliser, de sorte qu'ils ne sont pas en collision avec ceux du principal EXE ou DLL. C'est ce que MFC fait lorsqu'il est utilisé comme une bibliothèque statique. Vous pouvez également utiliser ID de ressource de chaîne (cela ne fonctionne pas pour les ressources STRINGTABLE).
  4. Votre bibliothèque statique peut être livré avec une DLL de ressource distincte.

Autres conseils

La seule chose que vous devez faire pour utiliser les ressources (images, dialogues, etc ...) dans une bibliothèque statique dans Visual C ++ (2008), est comprennent .res associés de la bibliothèque statique dans votre projet. Cela peut être fait à « Paramètres du projet / Linker / Input / dépendances supplémentaires ».

Avec cette solution, les ressources de la bibliothèque statique sont emballés dans le .exe, de sorte que vous n'avez pas besoin d'une DLL supplémentaire. Malheureusement, Visual Studio ne comprend pas le fichier .res automatiquement comme pour le fichier .lib (lors de l'utilisation des « dépendances • Figuration de projet »), mais je pense que ce petit pas supplémentaire est acceptable.

Je l'ai cherché très longtemps pour cette solution, et maintenant il me surprend, il est aussi simple que cela. Le seul problème est qu'il est tout à fait en situation irrégulière.

Je suis juste allé à travers ce avec le compilateur Visual Studio MS. Nous avons quelques projets convertissons hérités de DLL dans les bibliothèques statiques. Plusieurs de ces DLL avaient des ressources de dialogue ou une chaîne noyés dans la masse. Je suis en mesure de compiler les scripts .rc pour ces DLL dans notre principale application en les incluant dans le fichier script RC de l'application principale via le mécanisme « TEXTINCLUDE ». Je l'ai trouvé plus facile de le faire en éditant le fichier RC directement, mais Visual Studio fournit un peu plus mécanisme de « wizardy » aussi bien. La mise en œuvre est très probablement différent dans d'autres compilateurs.


Pour manipuler directement le script principal RC:

.1. Dans la section « 2 TEXTINCLUDE », inclure le fichier d'en-tête qui définit les ID de ressource pour votre bibliothèque. La syntaxe est

2 TEXTINCLUDE 
BEGIN
    "#include ""my_first_lib_header.h""\r\n"
    "#include ""my_second_lib_header.h""\0" 
END

0,2. Dans la section "3 TEXTINCLUDE", inclure le script RC de votre bibliothèque.

3 TEXTINCLUDE
BEGIN
    "#include ""my_first_library.rc""\r\n"
    "#include ""my_second_library.rc""\0"
END

Les étapes 3 et 4 devrait se faire automatiquement, mais je l'ai trouvé était plus fiable pour les entrer simplement moi-même, plutôt que selon le compilateur de script de ressources de Microsoft pour prendre soin des choses.

0,3. Ajoutez le fichier d'en-tête avec vos ressources bibliothèques définit à la liste en lecture seule des symboles. Cette liste est habituellement près du sommet du fichier.

#define APSTUDIO_READONLY_SYMBOLS
#include "my_first_lib_header.h"
#include "my_second_lib_header.h"
#undef APSTUDIO_READONLY_SYMBOLS

0,4. Inclure le script RC de votre bibliothèque dans la section APSTUDIO_INVOKED. Ceci est généralement au bas du fichier.

#ifndef APSTUDIO_INVOKED
#include "my_first_library.rc"
#include "my_second_library.rc"
#endif 

Vous pouvez également faire tout cela automatiquement par l'IDE de Visual Studio, mais je l'ai trouvé ne pas toujours appliquer quand je m'y attendais à.

  1. Ouvrez la fenêtre "Affichage des ressources" dans Visual Studio.
  2. Faites un clic droit sur le fichier de ressources de votre application principale et choisissez « Include des ressources ... » dans le menu contextuel.
  3. Dans la case « Lecture seule directives de symboles, » ajouter les instructions include pour les fichiers .h qui définissent les ressources ID de vos bibliothèques.
  4. Dans la case « directives de compilation », ajoutent les déclarations comprennent pour le script .rc de votre bibliothèque.
  5. Cliquez OK. Vous pouvez également déclencher manuellement la compilation de script RC, pour vous assurer qu'il arrive.

Si votre script de ressources de la bibliothèque fait référence à tous les fichiers sur le disque (fichiers texte, des fichiers d'icônes, etc.), vous devez vous assurer que le principal projet d'application sait où les trouver. Vous pouvez copier ces fichiers quelque part votre application peut les trouver ou vous pouvez ajouter un chemin d'inclusion supplémentaire dans les paramètres du compilateur.

Pour ajouter un chemin supplémentaire comprennent:

  1. Ouvrez la fenêtre des propriétés de votre application principale.
  2. Sélectionnez "Propriétés de configuration / Ressources / General" dans le volet de navigation à gauche.
  3. Dans la liste des propriétés, Entrez tous les chemins pertinents à côté de « supplémentaires include ».

Je ne pense pas. Bibliothèque statique ne dispose pas de son propre HINSTANCE. Il est le code est exécuté dans le contexte de DLL ou EXE qui relie. Voilà pourquoi toutes les ressources vont essayer de charger à partir du code de la bibliothèque statique sera de cette DLL / EXE englobante.

Je l'ai fait ce genre de ressources réutilisation avec une DLL si, dans la mesure où il a son propre espace d'adressage, et vous pouvez appeler LoadResource avec HINSTANCE de DLL.

Selon des outils Visual Studio 2010, le développement de Microsoft apparemment ne peut pas gérer correctement compilé des données de ressources dans les bibliothèques statiques du tout.

Pour distribuer un fichier de ressources compilé (un fichier .res), vous avez deux choix:

  1. Distribuez les fichiers .res séparément et charger le code client de lier contre eux;
  2. Utilisez cvtres pour fusionner plusieurs fichiers .res en un seul objet (.obj) fichier et fournir séparément.

Notez que vous ne pouvez pas lib dans des fichiers objets créés avec cvtres. Si plusieurs fichiers d'objets sont fournis, lib se plaint comme si que plusieurs fichiers .res ont été donnés; si un seul fichier d'objet est fourni, lib ne se plaint pas, mais l'éditeur de liens ignore simplement les données de ressources incorporées dans le fichier lib.

Il est peut-être le cas qu'il existe un moyen de forcer l'éditeur de liens à lire et à relier les libbed dans les données de ressources (avec une option de ligne de commande, la manipulation de la section et ainsi de suite), car les données de ressources est en effet disponible dans le bibliothèque (comme dumpbin révèle). Jusqu'à présent, je ne l'ai pas trouvé une solution, et, à moins que celui-ci est prêt à pirater les outils de développement, rien de mieux que cette solution simple ne vaut probablement pas l'effort.

La seule façon d'expédier des données de ressources dans une bibliothèque statique (dans ce cas, avec une bibliothèque statique) est de distribuer les ressources séparément et les lier explicitement dans le code client. L'utilisation cvtres peut réduire le nombre de fichiers de ressources distribués à un, si vous avez beaucoup d'entre eux.

La méthode recommandée est de fournir une dll avec les ressources en même temps que votre bibliothèque.

Lorsque la méthode suivante est utilisée, une ressource (dans cet exemple, une icône) peut être utilisé en tant que partie intégrante d'une bibliothèque statique et une telle bibliothèque peut être utilisée par tout type d'application, incluant une console one (qui doesn « t ont un segment de ressources que ce soit).

  1. Icône est converti en un tableau statique de BYTE. bin2c peut être utilisé pour cela.
  2. Les données sont converties en une poignée de HICON. Voici comment je l'ai fait:

    HICON GetIcon()
    { 
       DWORD dwTmp;
       int offset;
       HANDLE hFile;
       HICON hIcon = NULL;
       offset = LookupIconIdFromDirectoryEx(s_byIconData, TRUE, 0, 0, LR_DEFAULTCOLOR);
       if (offset != 0)
       {
          hIcon = CreateIconFromResourceEx(s_byIconData + offset, 0, TRUE, 0x00030000, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
       }
       return hIcon;  
    }
    
  3. GetIcon est utilisé au lieu de LoadIcon. Au lieu d'appeler:

m_hIcon = ::LoadIcon(hInstanceIcon, MAKEINTRESOURCE(pXMB->nIcon));

Ensuite, appelez

m_hIcon = GetIcon()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top