|
Dernière réponse | ||
---|---|---|
Sujet : [VC++] création d'une dll et probleme avec GetProcAddress | ||
BENB |
|
Aperçu |
---|
Vue Rapide de la discussion |
---|
BENB |
|
darthguy | Ouaip. De toutes manieres, t'as forcement la dependance dans un sens. Mais je vois pas quel est l'interet de faire en sorte que se soit la dll qui soit dependante et pas l'inverse. Ca te permet d'exporter des objets plus simplement ? |
BENB |
|
darthguy | Au pire, rien ne t'empeche d'avoir des fonctions en points d'entree et de les faire retourner des objets... |
SoWhatIn22 | pas simple ton truc. Je vais quand même aller voir ca de plus plres. Ca pourrait être instructif.
merci ;) |
BENB | Une Factory une Usine a classe, elle permet d'instancier des classes inconnues derivees d'une classe mere connue en general. Ce peut etre une methode ou une classe. Une classe permet d'en faire des liste avec des icones + description de la classe instanciee par l'usine.
On peut donc accoitre facilement les fonctionnalites d'un programme en chargeant des Dll qui contiendront des classes + factory. ces dll importent la classe de base qui est dans l'exe donc la Dll depends de l'exe et non le contraire, a la compil + link sera genere un .lib en plus de l'exe, et la Dll sera compilee avec le .lib Au run le prog ne charge pas la Dll implicitement (il ne la connait pas), mais par un LoadLibrary, et la il lui faut recuperer la factory. Si c'est une methode il va faire un GetProcAdress. Si c'est une classe on peut instancier un exemplaire de celle-ci dans la Dll. La Factory dans son constructeur s'enregistre dans une liste, et le tour est joue. Bien sur le probleme c'est que la Dll depend de l'exe et ne peut etre utilisee qu'avec lui. Ceci dit en mettant les classes meres dans une autre Dll dont dependent a la fois l'exe et la Dll courante on resoud ce probleme... Bon bien sur on peut aussi utiliser COM, mais c'est moins rigolo... |
robUx4 | pareil : pas compris mais interressé... |
SoWhatIn22 |
|
seblamb |
|
BENB | SoWhatIn22 > Une factory, tu n'a generalement besoin que d'une instance, donc tu declare une globale de ce type dans la Dll oui
sinon tu peux faire des chargement explicites en utilisant le .lib... le .lib de l'exe pour compiler la Dll... et du coup c'est l'exe qui fait un LoadLibrary et pas de Pb pour echanger classes et methodes C++... |
SoWhatIn22 |
|
robUx4 | Und es gros problèmes du C++ dans une DLL, c'est que tu peux pas charger une adresse de classe dans la DLL (un pointeur sur une classe) et la caster en la classe que tu veux. Même en supposant que c'est la même classe. Ca marche que dans le cas où t'as le même compilateur. Parce que les variables d'instances seront pas forcément placées et alignées pareil en mémoire.
C'est pour ca que je dis qu'une DLL c'est plutôt pour du C (et des structures) et pas trop pour le C++... Enfin, j'ai jamais vérifié ce que je dis, mais y a de fortes chances. Si tu maitrises les 2 cotés de la DLL, alors utilises un .lib. Un .def sert pas à grand chose puisque si t'utilises du C++, le .lib suffit. Si t'utilises un autres langages, tu pourras pas avoir la notion des objets C++... Dans ce 2e cas, il faut que tu fasses une interface C (extern "C" ) à tes classes, en passant à chaque fonction C (correspondant à une méthode public) un cookie (le this). |
SoWhatIn22 |
|
BENB |
|
SoWhatIn22 |
|
BENB |
|
SoWhatIn22 |
|
BENB | Tu dois pouvoir aussi faire un .def dans lequel tu donne le nom d'export de certaines fonctions... |
seblamb | mais tu n'as plus besoin de faire GetProcAdresse pour ces fonctions.
Tu fait un GetProcAdresse sur la fonction qui te renvois un pointeur sur un objet du type de la classe qui se trouve dans la dll. Ensuite tu utilise le pointeur comme d'hab. [edtdd]--Message édité par seblamb--[/edtdd] |
SoWhatIn22 |
|
seblamb | Il suffit de créer une fonction C qui encapsule le contructeur.
Après tu peux appeler directement les fonctions de ta classe déclarées avec le mot clef "_export". |
SoWhatIn22 | >Ah ben les DLL ca peut pas marcher avec du C++, juste du C! Si ca fonctionne. Sans probleme, même. Si le projet inclue les headers et le .lib généré en même temps que la dll, alors aucun soucis. Le probleme vient lors du chargement dynamique de la dll et lorsque l'on veut alors récuperer des pointeurs sur les fonctions. En fait, les fonctions sont bien exportées, mais les noms sont un peu différents. Et en fait, ces noms sont produits par le compilateur lui même, et il n'y a pas de norme la dessus. Donc les noms peuvent changer selon que la dll est générée avec un compilateur ou un autre. Par contre, ce que dit BENB est tout à fait vrai. Disons que rajouter des 'wrapper functions' rajoute encore une petite couche d'interface. C'est cela que je voulais essayer d'éviter. Mais apparement ca ne va pas être possible. Donc: wrappers... |
BENB | le plus simple c'est de faire c'est de faire une fonction extern "C" donc chargeable par LoadLibrary sans Pb qui renvoie des pointeurs sur les methodes C++ ou qui fabrique les classes... |
robUx4 | Ah ben les DLL ca peut pas marcher avec du C++, juste du C!
Parce qu'une methode virtuelle ou une méthode pas statique ca peut pas s'appeler comme ca. Une DLL c'est une bibliothèque de fonctions (méthodes statiques en C++)... M'enfin, la méthode que je t'ai dis peut fonctionner... |
SoWhatIn22 | > regarde les exports et la tu verras des noms a rallonge
ben en effet, ya des noms à rallonge. En fait, ca parait logique, puisqu'en C++ une meme fonction peut avoir un nombre d'arguments différents, et 2 classes différentes peuvent avoir une fonction du même nom. D'ou la decoration du nom des fonctions. Le probleme, c'est que cela ne m'arrange pas du tout... Parce que je ne crois pas qu'on puisse savoir à l'avance comment s'appelle ce nom. Bref, les dll en c++, c'est le bordel si on veut les charger dynamiquement. Y'aurrait bien le moyen de mettre une interface en C, mais bon, ca fait encore une couche en plus, mais c'est lourd. Je vais quand même essayer un de creuser un peu le sujet. On va bien voir. merci à tous. |
robUx4 | Yep y a probablement des underscores ou un truc comme ca.
Pour savoir tu peux compiler avec le .h mais SANS le .lib et au link il te dit les fonctions qu'il manque... Sinon, le DllMain n'est pas obligatoire ! (je m'en passe très bien) |
seblamb | Sous C++ Builder il y a une option pour résoudre ce problème mais sous Visual je sais pas.
Sinon tu peux créer un .def avec le nom de fonctions |
Guz |
|
SoWhatIn22 | oups... faute de frappe...
HINSTANCE hLib = LoadLibrary("myDll.dll" ); FARPROC fp_func = GetProcAddress(hLib, "fonction1" ); c'est tout. En fait, je viens de trouver d'ou vient l'erreur. Par contre, je n'arrive pas encore à l'exliquer... Si ma dll est compilée avec des fichiers d'extention .cpp et .hpp, le nom des fonctions exportées ne correspond plus au nom originial des fonctions. Par contre, si je renomme ces fichiers .c et .h, puisque pour le moment il n'y a que de C, alors tout fonction correctement. C'est gênant par ce que à terme, je voudrais quand même exporter des classes et des fonctions C++. |
SoWhatIn22 | HINSTANCE hLib = LoadLibrarymyDll.dll" );
FARPROC fp_func = GetProcAddress(hLib, "fonction1" ); c'est tout. En fait, je viens de trouver d'ou vient l'erreur. Par contre, je n'arrive pas encore à l'exliquer... Si ma dll est compilée avec des fichiers d'extention .cpp et .hpp, le nom des fonctions exportées ne correspond plus au nom originial des fonctions. Par contre, si je renomme ces fichiers .c et .h, puisque pour le moment il n'y a que de C, alors tout fonction correctement. C'est gênant par ce que à terme, je voudrais quand même exporter des classes et des fonctions C++. |
seblamb | DllMain c'est la point d'entrée de la dll quand elle est chargée. Sa permet éventuellement d'initialiser des variables.
C'est obligatoire comme Winmain pour les EXE. Montre la partie du source qui charge les fonctions. |
SoWhatIn22 | hello,
des petits soucis. Je crée une dll avec VC++ 6.0. Dans une appli, j'inclu le .h correspondant et le .lib, et la pas de soucis, je peux utiliser les fonctions de la dll. Par contre, si j'essaye de charger la dll avec LoadLibrary et que j'essaye de faire un GetProcAddress pour récupperer un pointeur sur une des fonctions, alors pas moyen: pointeur NULL et erreur windows = ERROR_PROC_NOT_FOUND; Si qq1 a une idée? D'autre part, je ne comprends pas bien à quoi sert la fonction BOOL APIENTRY DllMain qu'il essaye de me générer. C'est visiblement un poiunt d'entrée pour la dll, mais le comportement est le même que je laisse cette fonction ou que je la vire. Encore une fois, si qq1 a des explications ou un lien, je suis preneur. Merci. |