2009-10-15 5 views
2

Je suis en train de créer mon propre framework en C++ (MSVS 2008) qui exporte un DLL avec un tas de fonctions pour un utilisateur de mon framework à utiliser/appeler. Au début, quand mon projet était encore petit, tout fonctionnait bien. J'ai compilé mon projet. Un MyFramework.dll et MyFramework.lib ont été crachés. J'ai fait semblant d'être un utilisateur; mettez le fichier MyFramework.dll dans le dossier Debug de mon nouveau projet VS, placez le fichier MyFramework.lib et MyFramework.h dans mon dossier de projet, # include-d MyFramework.h dans mon code et voilá, je pourrais appeler le (toujours simple) fonctions de cadre à partir de mon nouveau projet.Création d'une DLL qui lie à une autre DLL (MSVS2008 C++)

Mais maintenant j'ai élargi mon cadre. Il utilise maintenant une DLL externe (laissez-moi l'appeler Graphics.dll) et l'a inclus de la même manière (.dll dans le dossier Debug, .lib/.h dans le dossier du projet, #include Graphics.h dans le code). Le problème est que quand je ne crée pas MyFramework.dll/MyFramework.lib, incluez-le dans mon nouveau projet et construction, l'éditeur de liens se plaint de ne pas pouvoir inclure Graphics.h, qui était évidemment inclus dans MyFramework.dll quelque part.

Donc, ma question. Je voudrais que l'utilisateur de MyFramework.dll ait seulement à inclure les fichiers MyFramework. * Dans leur projet et ne pas avoir besoin de copier/coller toutes les bibliothèques externes que je décide d'utiliser dans MyFramework. Comment puis-je accomplir cela? J'ai jeté un coup d'oeil à this thread. Il dit quelque chose sur l'ajout d'un élément existant et en appuyant sur la petite flèche à côté du bouton "Ajouter", mais ... la flèche est inexistante dans ma version de MSVS ...

Aide est très appréciée.

Amitiés W. Spek

+1

l'éditeur de liens se plaignant d'un fichier include? en aucune façon! – stijn

+0

Vous avez raison, c'est le compilateur. –

Répondre

1

« Le problème est que quand je crée MyFramework.dll maintenant/MyFramework.lib, inclure dans mon nouveau projet et de construire, l'éditeur de liens se plaint de ne pas être en mesure d'inclure des graphiques .h, qui était évidemment inclus dans MyFramework.dll quelque part. "

Avez-vous mis le chemin d'accès au fichier d'en-tête? Le compilateur signale que le fichier d'en-tête ne se trouve pas dans le même répertoire que le fichier cpp converti et n'est pas non plus répertorié dans les répertoires include supplémentaires.

Aller projet-> Propriétés puis sélectionnez C/C++

La première option vous verrez est "supplémentaire include". Vous devez mettre le chemin de votre en-tête Graphics.h là-dedans avec tous les autres chemins nécessaires tous les points-virgule séparés. Le projet que j'ai ouvert au mo a, par exemple: "../AudioLibrary ;../CoreLibrary;"

Modifier: De vos commentaires au poste de Mark vous dites que vous voulez intégrer le Graphics.dll dans votre DLL. Ma réponse est la suivante:

Si vous n'avez pas le code source à Graphics.dll alors vous avez un problème. Ce que vous demandez est possible mais très complexe à faire. Fondamentalement, vous ne pouvez pas utiliser LoadLibrary. Vous serez obligé d'écrire le vôtre pour LoadLibaray et GetProcAddress qui regarderont la DLL incorporée et n'essaieront pas de la trouver sur le disque ... Son faisable mais vous devrez faire beaucoup de lecture sur le Portable Executable (PE) file structure.

+0

Et cela fixe exactement ce que je ne veux pas avoir à faire. Que puis-je faire dans mon projet "MyFramework", pour ne pas avoir à inclure des fichiers externes dans mon nouveau projet qui utilise MyFramework.dll? –

+0

Eh bien, vous devez savoir à quoi ressemble le prototype de la fonction. Utiliser GetProcAddress, comme suggéré par Mark, est très bien, mais soit vous devez créer un fichier d'en-tête qui a une copie de la substance dans Graphics.h ou vous devez inclure l'original Graphics.h. Sinon, comment le compilateur peut-il savoir quels sont les paramètres nécessaires? – Goz

+0

Je devrais également souligner que si vous allez utiliser GetProcAddress, vous devrez créer un tas de pointeurs de fonction corrects avec le prototype de fonction concerné intégré dans le pointeur. – Goz

0

Si vous ne souhaitez pas obliger l'utilisateur à inclure ou à inclure Graphics.h, vous pouvez utiliser LoadLibrary pour charger dynamiquement Graphics.dll lors de l'exécution.

Cela signifie que l'utilisateur pourra compiler avec MyFramework sans Graphics.dll étant disponible, il peut être judicieux de faire une sorte de rapport d'erreur si LoadLibrary échoue.

Une fois que vous avez appelé avec succès LoadLibrary sur Graphics.dll, vous devrez importer manuellement chaque fonction (et sa signature) en utilisant GetProcAddress - cela vous donnera en fait des pointeurs de fonction. Comment vous stockez les pointeurs de fonction est à vous; Je préfère généralement avoir une classe autour des fonctions importées, mais rien ne vous empêche de conserver les pointeurs de fonction dans la portée globale.


Comme mentionné dans les commentaires, si vous ne voulez pas distribuer Graphics.dll du tout, il devra être une bibliothèque statique (à savoir « construit » à MyFramework.dll). Si vous voulez voulez distribuer Graphics.dll (de sorte que l'utilisateur peut utiliser Graphics.dll sans MyFramework.dll), alors l'approche ci-dessus reste la meilleure option. Vraiment, l'approche ci-dessus suppose que vous distribuez Graphics.dll avec MyFramework.dll, mais que l'utilisateur n'a pas nécessairement Graphics.h disponible.

+0

Mais probablement l'utilisateur aura toujours besoin d'une copie distincte de Graphics.dll quelque part sur son disque dur, non? Cela aussi est une situation indésirable. L'utilisateur n'a pas besoin de connaître l'existence de Grpahics.dll. Il devrait seulement avoir à se soucier des fichiers MyFramework. * ... –

+0

Parlez-vous de l'incorporation de la DLL dans l'exécutable? Si c'est le cas, utilisez une bibliothèque statique et non une bibliothèque dynamique! – Goz

+0

Oui, je parle de l'incorporation de Graphics.dll dans MyFramework.dll. Donc, la suggestion est une bibliothèque statique? Mais que voulez-vous dire? rendre statique la bibliothèque MyFramework ou inclure une bibliothèque graphique statique dans MyFramework.dll. Veuillez noter que je n'ai pas de code source pour Graphics.dll, à l'exception de Graphics.h. –

2

Ce qui se passe, c'est que l'utilisateur inclut l'un des fichiers d'en-tête de votre bibliothèque. Ce fichier inclut alors "graphics.h". Si vous ne voulez pas que vos utilisateurs aient accès à ce fichier, vous devez le cacher de l'interface de votre bibliothèque.

Votre bibliothèque doit avoir des fichiers d'en-tête d'API publics et des fichiers d'en-tête d'implémentation privés. Votre utilisateur inclut uniquement les fichiers d'en-tête d'api publics, ceux-ci n'incluant pas les fichiers d'inclusion tiers ou privés. Lorsque ces fichiers font référence à des types privés ou à des types de tiers, ils ne peuvent utiliser que des pointeurs ou des références, ceux-ci sont déclarés en avant. Cela permet à la partie privée d'une classe d'utiliser du code de bibliothèque privée et des types tiers.

Les chances sont en utilisant le Pimpl Idiom pour résoudre ce problème pour vous.

+0

Je pense que vous pourriez avoir raison. En ce moment, j'inclus Graphics.h dans le fichier d'en-tête de l'interface MyFramework.h. C'est faux. J'ai aussi parlé à mon superviseur qui m'a dit la même chose.C'est pourquoi le compilateur de l'utilisateur se plaint de manquer le fichier Graphics.h. Je vais jeter un coup d'oeil au modèle PIMPL et voir si je peux résoudre mon problème. Je dois le faire un peu plus tard cependant. Je reviendrai sur la solution finale. –

+0

J'essayais d'utiliser une bibliothèque non gérée à partir d'une DLL managée en utilisant C++/CLI. Malheureusement, mon en-tête utilisait un en-tête OpenCV, ce qui signifiait qu'il avait besoin d'un bâtiment en mode mixte, ce qui ne fonctionnerait pas. L'utilisation de l'idiome Pimpl était exactement ce dont j'avais besoin – Fuzz

Questions connexes