DLL et #include

DLL et #include - C++ - Programmation

Marsh Posté le 29-05-2004 à 04:51:26    

Bonjour à tous,
 
pour créer une DLL, j'indique les dossiers où le compilateur peut trouver les fichiers que j'inclue dans la DLL.
 
Est-ce normal que je doive également les indiquer dans l'appli principale qui utilise la DLL?
 
J'utilise ce genre de fichier de déclaration, commun à la DLL et à l'appli principale:
 

Code :
  1. #ifndef DS_AffichH
  2. #define DS_AffichH
  3. #ifdef __DLL__
  4. #define IMPORT_EXPORT __declspec(dllexport)
  5. #else
  6. #define IMPORT_EXPORT __declspec(dllimport)
  7. #endif
  8. #include <dshow>
  9. #include <qedit>
  10. #include <d3d9>
  11. #include <vmr9>
  12. #include <sbe>
  13. #include <ATLBase>
  14. class IMPORT_EXPORT DS_Affich_Video
  15. {
  16. //...
  17. };
  18. #endif


 
Ce type de déclaration: #include <dshow> doit-elle être présente aussi pour l'appli principale? Il me semblait que pour l'appli principale, le .H ne servait qu'à indiquer les fonctions à utiliser?
 
Comment je peux éviter ça, si je peux l'éviter?

Reply

Marsh Posté le 29-05-2004 à 04:51:26   

Reply

Marsh Posté le 29-05-2004 à 07:53:31    

Et bien tu n'as qu'a faire tes #include <dshow> et autres dans un autre header, que la source de ta dll sera la seule a inclure. Pourquoi avoir mis dans ce header ce genre de includes?
 
Si c'est parce que la classe qui y est définie contient des objets membres dont le type est défini dans les dshow, d3d8 et autres, tu ne dois pas changer ton code : il faut que le compilateur connaisse la taille de ces objets lorsque tu instancieras un DS_Affich_Video, et donc tu dois laisser les includes.
 
A titre informatif, ton probleme n'a rien de spécifique aux DLL, tu peux tout aussi bien le rencontrer lorsque tu compiles deux fichiers cpp séparément et que l'un utilise les fonctionnalités de l'autre.


Message édité par Ace17 le 29-05-2004 à 08:00:54
Reply

Marsh Posté le 29-05-2004 à 14:22:04    

Ace17 a écrit :

Et bien tu n'as qu'a faire tes #include <dshow> et autres dans un autre header, que la source de ta dll sera la seule a inclure. Pourquoi avoir mis dans ce header ce genre de includes?
 
Si c'est parce que la classe qui y est définie contient des objets membres dont le type est défini dans les dshow, d3d8 et autres, tu ne dois pas changer ton code : il faut que le compilateur connaisse la taille de ces objets lorsque tu instancieras un DS_Affich_Video, et donc tu dois laisser les includes.
 
A titre informatif, ton probleme n'a rien de spécifique aux DLL, tu peux tout aussi bien le rencontrer lorsque tu compiles deux fichiers cpp séparément et que l'un utilise les fonctionnalités de l'autre.


 
OK, merci. Quant à pourquoi ces include, c'est parce j'ai dans ma classe des objets et des fonctions dont la déclaration est dans ces include...

Reply

Marsh Posté le 29-05-2004 à 14:58:34    

j'peux vous demander a quoi peut servir les dll? :jap:


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 29-05-2004 à 15:37:18    

Les dll, c'est des librairies qui sont liées a ton programme au moment de l'execution ( contrairement aux librairies statiques ). Imagine par exemple que tu inventes un format de fichier, et que désires créer plusieurs utilitaires qui réalisent chacun une opération sur ce type de fichiers.
Tu as donc besoin d'un module qui offre des fonctionnalités de lecture et d'écriture dans ce format de fichier : soit tu fais un module statique, mais il te faudra recompiler tous les utilitaires a chaque fois que ton format évoluera, soit tu fais un module dynamique, ( une DLL donc ) et alors tes utilitaires passeront tous cette meme DLL et suivront donc les évolutions du format sans que tu n'aies besoin de les recompiler.
 
C'est un peu ce qui se passe avec DirectX : Les jeux utilisent les DLL de DirectX, sans se soucier de leur implémentation, et la liaison avec les fonctions importées se fait a l'execution. Ainsi, quand tu mets a jour DirectX, tes jeux peuvent adopter un comportement différent ( nouvelles options graphiques, nouveaux effets, jeu plus rapide... ) bien qu'ils n'aient évidemment pas été recompilés.


Message édité par Ace17 le 29-05-2004 à 15:38:04
Reply

Marsh Posté le 29-05-2004 à 16:13:25    

ok merci, ta reponse est tres clair :jap:


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 29-05-2004 à 17:45:51    

Par contre comment ça marche quand on ajoute des fonctions à la DLL?
Si on veut que le programme les prenne en compte, on remplace le .LIB, et on doit recompiler?

Reply

Marsh Posté le 29-05-2004 à 18:02:46    

oui, il faut tout recompiler.

Reply

Marsh Posté le 29-05-2004 à 18:46:55    

ok, merci

Reply

Marsh Posté le 29-05-2004 à 19:15:12    

Parce que je ne sais pas comment ça se passe au moment de la compilation:
 
dans ma dll j'inclue un fichier Divers.h et j'ajoute Divers.cpp dans lesquels se trouvent des fonctions, ... diverses, utilisées par mon application principale.
 
Ma DLL utilise une seule fonction de ces fichiers. Est-ce que les fonctions inutilisées sont quand même ajoutées pour rien dans la DLL?
 
Et si oui est-ce une bonne solution que de créer un nouveau fichier où ne se trouve que cette fonction, que l'on incluerait à la fois dans la DLL et dans l'application principale?
 
En espérant avoir été clair ;)
 
Merci d'avance

Reply

Marsh Posté le 29-05-2004 à 19:15:12   

Reply

Marsh Posté le 29-05-2004 à 20:43:30    

Bon déja, on inclut pas un .h dans une dll mais dans un .cpp. Ca ne veut rien dire sinon!
Ensuite, quels sont les fichiers qui composent ton projet?  

Reply

Marsh Posté le 31-05-2004 à 03:34:45    

Ben dans Divers.cpp j'ai des fonctions de conversion de date, de séparation de chaines (du style 0-1-2-3-4- remplit un vecteur avec chacune des valeurs séparées par un "-" ),...,  et dans Divers.h j'ai leurs déclarations.
 
Dès que dans mon projet principal j'ai besoin de l'une de ces fonctions, je mets #include "Divers.h".
 
Mais dans ma DLL j'ai ajouté "Divers.cpp" au projet, et j'ai fait un #include "Divers.h" dans le cpp de la DLL.
 
Mais comme je n'utilise qu'une seule fonction dans ma DLL, je me demandais si on pouvait laisser Divers.h et Divers.cpp tels quels, et que le compilo n'intégrait pas les fonctions inutilisées dans la DLL, ou bien s'il valait mieux recréer un fichier .cpp et .h avec uniquement la fonction utilisée, pour "alléger" la DLL.
 
Voilà, j'espère que j'ai été plus clair (on peut espérer)

Reply

Marsh Posté le 31-05-2004 à 09:08:45    

Ouais, j'ai compris ton probleme.  
 
Bon déja, le .h il n'intervient pas dans l'histoire. Il servira juste a empecher le compilateur de gueuler parce qu'il ne connait pas les fonctions que tu invoques dans ton projet. Donc peu importe ce que tu mets dans ton .h, dans tous les cas ou ca compilera, la taille sera la meme.
 
En d'autres termes, ce n'est pas la .h qui va déterminer quelles vont etre exportées.
 
Ensuite, quand tu crées ta DLL, comment peut elle savoir que seule une seule fonction va etre employée? La DLL générée contient donc le code de TOUTES les fonctions exportées, ajouté a cela les fonctions reférencées par les fonctions exportées.
 
Bref, si tu veux alléger ta DLL, il te faut donc en compiler une version où tu n'exportes que les fonctions effectivement utilisées par ton application.
 
Maintenant, en quoi la taille est-elle un probleme pour toi? Si la DLL est vraiment volumineuse, dans ton cas, ne vaudrait-il pas mieux faire 2 DLL ?

Reply

Marsh Posté le 31-05-2004 à 11:15:10    

C4est vrai que la taille n'est pas un problème... Mais bon c'était une question que je m'étais posée.
 
En tous cas, merci de ton aide et de tes éclaircissements...

Reply

Marsh Posté le 31-05-2004 à 12:01:40    

comment tu fais pour appeller la foncton qui est dans ta DLL?


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 31-05-2004 à 12:07:49    

appeller = nommer ou invoquer?
 
Pour invoquer une fonction de la dll, deux méthodes :  
- Tu fais comme tu fais pour n'importe quelle autre fonction, mais il faut que son prototype soit connu ( d'ou l'intéret d'inclure le .h qui contient ce prototype ) et il faut lier avec la librairie "ma_dll.lib" ( qui contient les informations nécessaires pour générer la table d'importation de ton executable final)
 
- Tu invoques LoadLibrary avec comme argument "ma_dll.dll", puis tu fais GetProcAddress(hDLL, "nom_exporté_de_ma_fonction" ) pour obtnir l'addresse de la fonction que tu veux invoquer. Mais c'est déconseillé dans le cas ou c'est toi qui a créé la DLL dans la mesure ou si c'est du C++ les noms seront décorés et donc une fonction qui sera nommée MaFonction(int, int) apparaitra comme MaFonction@2I2098FYZ et donc forcément c'est moins pratique.

Reply

Marsh Posté le 31-05-2004 à 13:50:43    

si j'ai bien compris la premiere methode, tu crés ta dll avec ces fonctions et leurs déclarations dans le .h (extern void ...; ou bien des classes), puis dans ton programme ou tu utilises les fonctions qui sont dans la dll tu met #include"ma_dll.lib" , c'est ca ou je suis a l'ouest?  :whistle:


Message édité par neg'gwada le 31-05-2004 à 13:52:03

---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 31-05-2004 à 13:52:55    

neg'gwada a écrit :

si j'ai bien compris la premiere methode, tu crés ta dll avec ces fonctions et leurs déclarations dans le .h (extern void ...; ou bien des classes), puis dans ton programme ou tu utilises les fonctions qui sont dans la dll tu met #include"ma_dll.lib" , c'est ca ou je suis a l'ouest?  :whistle:


Lis la réponse que j'ai faite à Cherrytree dans ce post, ça devrait t'éclairer :
http://forum.hardware.fr/forum2.ph [...] 798&cat=10


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 31-05-2004 à 13:55:50    

ok c cool je vois mieux maintenant :jap:


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 31-05-2004 à 14:12:45    

sous VC++ je dois utiliser le MFC AppWizard(dll) pour en creer un ? ou bien il y a une autre facon de faire ses dll?


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 31-05-2004 à 14:47:17    

Ben il suffit de mettre Dynamic Link Library... les DLL n'utilisent pas toutes MFC, heureusement!

Reply

Marsh Posté le 31-05-2004 à 17:30:20    

Ace17 a écrit :

- Tu invoques LoadLibrary avec comme argument "ma_dll.dll", puis tu fais GetProcAddress(hDLL, "nom_exporté_de_ma_fonction" ) pour obtnir l'addresse de la fonction que tu veux invoquer. Mais c'est déconseillé dans le cas ou c'est toi qui a créé la DLL dans la mesure ou si c'est du C++ les noms seront décorés et donc une fonction qui sera nommée MaFonction(int, int) apparaitra comme MaFonction@2I2098FYZ et donc forcément c'est moins pratique.


 
Mais mettre extern "C" ne permet-il pas d'éviter la décoration du nom des fonctions?

Reply

Marsh Posté le 31-05-2004 à 17:40:41    

Oui, tout a fait. Mais tu ne pourras pas exporter de fonctions surchargées, et encore moins de classes...

Reply

Marsh Posté le 31-05-2004 à 21:30:24    

Ah, je savais pas ça...
 
Ben merci ;)

Reply

Marsh Posté le 31-05-2004 à 21:56:05    

Ben ouais, les noms des fonctions, si on les décore, c'est pas pour faire joli!
 
 
 
 
 
:D

Reply

Marsh Posté le 02-06-2004 à 02:49:05    

Sinon je me pose encore une question:
 
J'ai créé
* une DLL qui des classes utilisant DirectShow pour manipuler de la vidéo (DShow.dll)
* une DLL contenant les classes et fenêtres pour réaliser un montage vidéo (Montage.dll), et qui utilise la première DLL pour justement manipuler la vidéo.
* Une DLL avec classes et fenêtres pour afficher une fenêtre pour lire la vidéo (une sorte de MediaPLayer quoi), qui utilise la première DLL (pour lire la vidéo), mais aussi la deuxième DLL pour exporter des séquences vidéos choisies par l'utilisateur dans la fenêtre de montage vidéo contenue par la deuxième DLL.
 
Donc je me retrouve à chaque fois à ajouter aux projets les .LIB des DLL utilisées, avec aussi les répertoires où il peut aller chercher les includes, si bien que pour la DLL d'affichage vidéo je me retrouve à ajouter les mêmes fichiers que pour la DLL de montage.
 
Je suis obligé de passer par là?
Peut-être y a-t-il une meilleure solution?
Si oui laquelle?
J'ai été clair? ;)
 
Merci d'avance

Reply

Marsh Posté le 02-06-2004 à 19:17:05    

Non t'es pas clair, mais je crois comprendre. Et pour te répondre, non, t'as pas besoin d'ajouter "machin.lib" au projet "bidule" (qui genere "bidule.lib" et "bidule.dll" ), meme si bidule utilise machin. Le seul endroit ou tu aies besoin de tout ca, c'est dans le projet qui génere un executable, car c'est la que se fait l'édition de liens.

Reply

Marsh Posté le 03-06-2004 à 00:17:08    

J'essaierai de faire ça demain, parce que là j'ai pas le PC, mais il me semble que je sois obligé d'ajouter tout ça pour créer la DLL.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed