Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
899 connectés 

  FORUM HardWare.fr
  Programmation

  [VC++] création d'une dll et probleme avec GetProcAddress

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[VC++] création d'une dll et probleme avec GetProcAddress

n°50634
SoWhatIn22
Posté le 02-08-2001 à 13:47:25  profilanswer
 

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.

mood
Publicité
Posté le 02-08-2001 à 13:47:25  profilanswer
 

n°50639
seblamb
Posté le 02-08-2001 à 14:12:14  profilanswer
 

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.

n°50644
SoWhatIn22
Posté le 02-08-2001 à 14:32:10  profilanswer
 

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++.

n°50645
SoWhatIn22
Posté le 02-08-2001 à 14:32:56  profilanswer
 

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++.

n°50646
Guz
Posté le 02-08-2001 à 14:37:52  profilanswer
 

SoWhatIn22 a écrit a écrit :

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++.  




 
Avec des fichiers cpp, le nom de tes fonctions externes est plus complique que le nom dans ton fichier car y'a une description de la fonction. (ex : appartient a telle classe)
 
Compile ta DLL et avec Quickview regarde les exports et la tu verras des noms a rallonge, c'est eux que tu dois utiliser.
 
Salut.

n°50649
seblamb
Posté le 02-08-2001 à 14:41:48  profilanswer
 

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

n°50662
robUx4
misc coder
Posté le 02-08-2001 à 14:55:19  profilanswer
 

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)

n°50691
SoWhatIn22
Posté le 02-08-2001 à 16:12:37  profilanswer
 

> 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.

n°50694
robUx4
misc coder
Posté le 02-08-2001 à 16:23:15  profilanswer
 

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...

n°50705
BENB
100% Lux.
Posté le 02-08-2001 à 16:39:43  profilanswer
 

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...

mood
Publicité
Posté le 02-08-2001 à 16:39:43  profilanswer
 

n°50714
SoWhatIn22
Posté le 02-08-2001 à 16:46:29  profilanswer
 

>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...

n°50719
seblamb
Posté le 02-08-2001 à 16:55:38  profilanswer
 

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".

n°50734
SoWhatIn22
Posté le 02-08-2001 à 17:30:25  profilanswer
 

seblamb a écrit a écrit :

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".  




 
Ben non, parce que justement les fonctions déclarées avec _export verront leur nom changer, d'ou la nécessité d'écrire des fonctions d'interface.
 
De plus, si tu exportes directement la classe:
 
class __declspec(dllexport) myClass
{
   etc...
};
 
alors toutes les fonctions membres sont exportées automatiquement. Ca évite de définir une fonction d'interface en C pour toutes les méthodes et les attributs publiques.
Mais avec le GetProcAddress, ca ne fonctionne plus car tu ne connais pas le nom des fonctions.
 
Voila tout mon probleme.
 
remarque, juste pour info:
MSDN:
" You used the _export keyword, which is now obsolete. Use __declspec(dllexport) instead"

n°50736
seblamb
Posté le 02-08-2001 à 17:34:42  profilanswer
 

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]

n°50737
BENB
100% Lux.
Posté le 02-08-2001 à 17:36:12  profilanswer
 

Tu dois pouvoir aussi faire un .def dans lequel tu donne le nom d'export de certaines fonctions...

n°50740
SoWhatIn22
Posté le 02-08-2001 à 17:56:17  profilanswer
 

seblamb a écrit a écrit :

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.  
 
 




 
ton truc ne peux pas marcher, car comme tu ne peux pas exporter directement ta classe, son type n'est pas déclaré dans le code qui charge cette dll. Tu ne peux donc pas instancier une variable de ce type puisqu'il est inconnu. Donc tu peux à la limite prendre un void *. Sauf qu'après, impossible de lui appliquer des fonctions membres. Et le casting est impossible puisqu'encore une fois, tu ne connais pas le type.

n°50745
BENB
100% Lux.
Posté le 02-08-2001 à 18:18:31  profilanswer
 

SoWhatIn22 a écrit a écrit :

 
 
ton truc ne peux pas marcher, car comme tu ne peux pas exporter directement ta classe, son type n'est pas déclaré dans le code qui charge cette dll. Tu ne peux donc pas instancier une variable de ce type puisqu'il est inconnu. Donc tu peux à la limite prendre un void *. Sauf qu'après, impossible de lui appliquer des fonctions membres. Et le casting est impossible puisqu'encore une fois, tu ne connais pas le type.  




Bien sur que on peut exporter une classe...
ou alors j'ai ete dans un reve pendant quatre ans...

n°50749
SoWhatIn22
Posté le 02-08-2001 à 18:57:58  profilanswer
 

BENB a écrit a écrit :

 
Bien sur que on peut exporter une classe...
ou alors j'ai ete dans un reve pendant quatre ans...  




 
<B>D</B>ans le cas d'un chargement implicite de la dll, oui. Dans le cas d'un chargement explicite, donc avec LoadLibrary puis des GetProcAddress, non. Ou alors explique moi comment tu fais pour importer un type?
 
Dans mon exemple:
class __declspec(dllexport) myClass  
{  
  etc...  
};  
 
si tu charges la dll implicitement, alors le type myClass est connu. Avec un chargement explicite, il ne l'est pas.
 
Ou alors ya une subtilité que je n'ai pas vu? On m'aurait caché des choses?!

n°50779
BENB
100% Lux.
Posté le 03-08-2001 à 08:53:23  profilanswer
 

SoWhatIn22 a écrit a écrit :

 
 
<B>D</B>ans le cas d'un chargement implicite de la dll, oui. Dans le cas d'un chargement explicite, donc avec LoadLibrary puis des GetProcAddress, non. Ou alors explique moi comment tu fais pour importer un type?
 
Dans mon exemple:
class __declspec(dllexport) myClass  
{  
  etc...  
};  
 
si tu charges la dll implicitement, alors le type myClass est connu. Avec un chargement explicite, il ne l'est pas.
 
Ou alors ya une subtilité que je n'ai pas vu? On m'aurait caché des choses?!  




chargement explicite ou implicite, le type doit etre suffisament connu pour pouvoir etre instancie. en General les types de la Dll sont des derives d'un type connu et tu recuperes par GetProcAdress une methode "Factory" qui permet de construire ces nouveaux types...
Encore tu peu crer un type factory associe a chaque autre classe de la Dll, variables globales(*) de la Dll ils s'enregistrent dans une liste lors du chargement de celle-ci...
 
(*) evidement cette methodologie est criticable, je cite une methode simple, elle peut etre construite de maniere plus sioux.

n°50798
SoWhatIn22
Posté le 03-08-2001 à 10:28:52  profilanswer
 

BENB a écrit a écrit :

 
chargement explicite ou implicite, le type doit etre suffisament connu pour pouvoir etre instancie. en General les types de la Dll sont des derives d'un type connu et tu recuperes par GetProcAdress une methode "Factory" qui permet de construire ces nouveaux types...




 
Tout à fait ok avec ça.
 

BENB a écrit a écrit :

 
Encore tu peu crer un type factory associe a chaque autre classe de la Dll, variables globales(*) de la Dll ils s'enregistrent dans une liste lors du chargement de celle-ci...




 
La je ne comprends pas bien ce que tu veux dire. Tu mets des types en variables globales? Je ne comprends pas ce que cela veux dire. Si tu peux m'éclairer...

n°50806
robUx4
misc coder
Posté le 03-08-2001 à 11:11:25  profilanswer
 

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).

n°50810
SoWhatIn22
Posté le 03-08-2001 à 11:22:14  profilanswer
 

robUx4 a écrit a écrit :

 
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++...




 
Si tu fais un chargement implicite, donc en compilant avec le .lib, tu peux exporter une classe sans aucun probleme. Je le fais et ca fonctionne tres bien. Le probleme survient quand on veut faire des chargements explicites avec un LoadLibrary. Et le chargement explicite est parfois bien pratique. Par exemple pour que ton programme puisse fonctionner même si la dll n'est pas présente.

n°50826
BENB
100% Lux.
Posté le 03-08-2001 à 11:54:01  profilanswer
 

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++...

n°50831
seblamb
Posté le 03-08-2001 à 12:05:05  profilanswer
 

BENB a écrit a écrit :

 
le .lib de l'exe pour compiler la Dll...



Tu peux être plus précis je vois pas trop ce que tu veux dire.

n°50834
SoWhatIn22
Posté le 03-08-2001 à 12:08:21  profilanswer
 

BENB a écrit a écrit :

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++...  




 
je suis désolé mais je n'arrive pas à comprendre ce que tu veux dire. Qu'est-ce que tu appelles une factory, exactement.
 
Et "le .lib de l'exe pour compiler la Dll": comprends pas du tout ce que tu veux dire :(
 
Apres, j'arrete de t'embeter, promis :D

n°50845
robUx4
misc coder
Posté le 03-08-2001 à 12:36:00  profilanswer
 

pareil : pas compris mais interressé...

n°50869
BENB
100% Lux.
Posté le 03-08-2001 à 13:24:10  profilanswer
 

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...

n°50873
SoWhatIn22
Posté le 03-08-2001 à 13:50:58  profilanswer
 

pas simple ton truc. Je vais quand même aller voir ca de plus plres. Ca pourrait être instructif.
merci ;)

n°50880
darthguy
Posté le 03-08-2001 à 14:01:56  profilanswer
 

Au pire, rien ne t'empeche d'avoir des fonctions en points d'entree et de les faire retourner des objets...

n°50890
BENB
100% Lux.
Posté le 03-08-2001 à 14:31:15  profilanswer
 

darthguy a écrit a écrit :

Au pire, rien ne t'empeche d'avoir des fonctions en points d'entree et de les faire retourner des objets...  




mais ces objets doivent etre connus pour etre retournes... d'ou la dependance...

n°50897
darthguy
Posté le 03-08-2001 à 14:36:08  profilanswer
 

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 ?

n°50906
BENB
100% Lux.
Posté le 03-08-2001 à 14:46:52  profilanswer
 

darthguy a écrit a écrit :

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 ?  




et d'en ajouter sans modifier l'executable, ce qui est comfortable quand ce sont tes clients qui font ces objets...

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation

  [VC++] création d'une dll et probleme avec GetProcAddress

 

Sujets relatifs
[JAVA] probleme d'affichage de texte sur video mpgC++ - Problème de passage de variable de type vector dans une fonction
[Java][php] Gros, tres gros probleme[Visual C++] A la création d'un dialogue, problème de Checkbox
Problème DLL ???IMPORTANT !! probleme en VBavec Excel et Word
Aide pour la création d'un formulaire Htm (DEBUTANT)a l'aide ! (probleme de base SQL /PHP)
Problème de DHTML 
Plus de sujets relatifs à : [VC++] création d'une dll et probleme avec GetProcAddress


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR