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

  FORUM HardWare.fr
  Programmation
  C++

  (win32) classe dans une dll

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

(win32) classe dans une dll

n°498343
blackgodde​ss
vive le troll !
Posté le 26-08-2003 à 12:02:08  profilanswer
 

bonjour, j'ai compilé une dll avec une classe dedans, dont j'ai la déclaration :
 
typedef class MaClasse
{
   public:
   void Membre();
} MaClasse, *pMaClasse;
 
comment faire pour l'instancier apres avoir chargé ma dll ?
 
HMODULE hMod = LoadLibrary("MaDLL" );


---------------
-( BlackGoddess )-
mood
Publicité
Posté le 26-08-2003 à 12:02:08  profilanswer
 

n°498357
chrisbk
-
Posté le 26-08-2003 à 12:06:37  profilanswer
 

typedef class <= what's that
 
 
Fo que tu reprennes tes cours sur les DLL  

n°498405
blackgodde​ss
vive le troll !
Posté le 26-08-2003 à 12:33:07  profilanswer
 

vaut mieux faire
 
class MaClasse {
//
};
typedef MaClasse * pMaClasse;
 
?


---------------
-( BlackGoddess )-
n°498409
chrisbk
-
Posté le 26-08-2003 à 12:34:45  profilanswer
 

c juste que je trouve ca moche :O
dans l'ensemble chui rarement fan des types qui cachent qu'un objet est un ptr... enfin bon c pas le pb
 
tu peux pas instance directement une classe comme tu compte le faire, ou alors il faut exporter ta classe de ta dll
 
T'utilise quoi cmme compilo ?

n°498423
blackgodde​ss
vive le troll !
Posté le 26-08-2003 à 12:42:39  profilanswer
 

j'utilise vc++7, dsl de pas l'avoir précisé :(
 
sinon, pour exporter ma classe il me semble que je doive faire :
 

Code :
  1. class __declspec(dllexport) MaClasse {
  2. //
  3. };


 
ou, d'apres le générateur de vc++ pour pouvoir utiliser le meme header pour la DLL et pour les executables qui l'appeleront :
 

Code :
  1. #ifdef MADLL_EXPORTS
  2. #define MADLL_API __declspec(dllexport)
  3. #else
  4. #define MADLL_API __declspec(dllimport)
  5. #endif
  6. class MADLL_API MaClasse {
  7. //
  8. };


 
ensuite donc je charge ma DLL avec LoadLibrary (c'est impératif)


---------------
-( BlackGoddess )-
n°498425
chrisbk
-
Posté le 26-08-2003 à 12:47:06  profilanswer
 

Citation :

ensuite donc je charge ma DLL avec LoadLibrary (c'est impératif)


 
hum
la c'est embetant
tu peux pas utiliser la lib que visual te recrache et la linker a ton exe ?

n°498427
gatorette
Posté le 26-08-2003 à 12:48:35  profilanswer
 

BlackGoddess a écrit :

ensuite donc je charge ma DLL avec LoadLibrary (c'est impératif)


 
Tu ne pourras donc pas importer directement des classes comme ça. En effet, la seule fontion disponible est alors GetProcAddress qui ne sait charger que des fonctions.
Il faut que tu passes par des techniques un peu différente. COM est celle utilisée en standard dans Windows mais tu peux faire des choses plus simple (une fonction dans ta dll qui fait un new et renvoie un pointeur vers ton objet et une fonction pour le deleter peut suffire).


---------------
each day I don't die is cheating
n°498445
ACut
Posté le 26-08-2003 à 13:27:11  profilanswer
 

gatorette a écrit :


 
En effet, la seule fontion disponible est alors GetProcAddress qui ne sait charger que des fonctions.
Il faut que tu passes par des techniques un peu différente. COM est celle utilisée en standard dans Windows mais tu peux faire des choses plus simple (une fonction dans ta dll qui fait un new et renvoie un pointeur vers ton objet et une fonction pour le deleter peut suffire).
 


Excellente info, gatorette, merci. (C'est un pb qui me taraudait moi aussi...)


---------------
NOUVEAU! Le guide de l'édition en version ebook : http://marcautret.free.fr/autret/150q-ebook/
n°498470
blackgodde​ss
vive le troll !
Posté le 26-08-2003 à 13:55:05  profilanswer
 

tu peux pas utiliser la lib que visual te recrache et la linker a ton exe ?
 
>> c'est pour créer un système de plugin, je ne peux pas me permettre de relinker mon projet à chaque ajout/suppression de plugin.
 
excellente idée gatorette merci, sinon aurais-tu des infos sur la technique COM ?


---------------
-( BlackGoddess )-
n°498478
chrisbk
-
Posté le 26-08-2003 à 13:59:19  profilanswer
 

bon, ben methode 3dsmax que je trouve de tres bon gout : classe de base avec methode virtuelle pure, deux fonction exportee de la dll :
 
->une donnant le nombre de plug in contenu
->une creant un objet "plugin numero i"
 
et roule simone

mood
Publicité
Posté le 26-08-2003 à 13:59:19  profilanswer
 

n°498498
blackgodde​ss
vive le troll !
Posté le 26-08-2003 à 14:13:56  profilanswer
 

je maitrise pas encore super bien le ++ du c ... je vais donc deja me documenter sur les méthodes virtuelles pures avant d'essayer de comprendre ...


---------------
-( BlackGoddess )-
n°498509
blackgodde​ss
vive le troll !
Posté le 26-08-2003 à 14:19:43  profilanswer
 

j'ai testé la méthode de gatorette :  
 
dans ma dll :
 

Code :
  1. #include <windows.h>
  2. class CTest
  3. {
  4. public:
  5. CTest();
  6. ~CTest();
  7. void Membre();
  8. };
  9. CTest::CTest()
  10. {
  11. MessageBox(NULL, "CTor", "CTest", NULL);
  12. }
  13. CTest::~CTest()
  14. {
  15. MessageBox(NULL, "DTor", "CTest", NULL);
  16. }
  17. void CTest::Membre()
  18. {
  19. MessageBox(NULL, "Membre", "CTest", NULL);
  20. }
  21. CTest* WINAPI _new()
  22. {
  23. return new CTest();
  24. }
  25. void WINAPI _delete(CTest* Test)
  26. {
  27. delete Test;
  28. }


 
j'ai exporté les fonctions _new et _delete
 
puis dans mon executable :
 

Code :
  1. #include <windows.h>
  2. class CTest
  3. {
  4. public:
  5. CTest();
  6. ~CTest();
  7. void Membre();
  8. };
  9. typedef CTest* (WINAPI* fnew)();
  10. typedef void (WINAPI* fdelete)(CTest* Test);
  11. int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cl, int ns)
  12. {
  13. HMODULE hMod = LoadLibrary("testdll" );
  14. fnew _new = (fnew)GetProcAddress(hMod, "_new" );
  15. fdelete _delete = (fdelete)GetProcAddress(hMod, "_delete" );
  16. CTest* test = _new();
  17. test->Membre();
  18. _delete(test);
  19. return 0;
  20. }


 
le problème à la compilation :
 
error LNK2019: symbole externe non résolu "public: void __thiscall CTest::Membre(void)" (?Membre@CTest@@QAEXXZ) référencé dans la fonction _WinMain@16


---------------
-( BlackGoddess )-
n°498516
chrisbk
-
Posté le 26-08-2003 à 14:22:25  profilanswer
 

joue la comme ca
 
:
 
DLL :
 

Code :
  1. class CTest
  2. {
  3. public:
  4. virtual void Membre()=0;
  5. };
  6. class CTest2:public CTest
  7. {
  8. public:
  9. virtual void Membre(){}
  10. }
  11. extern "C"
  12. {
  13. CTest* WINAPI _new()
  14. {
  15. return new CTest2();
  16. }
  17. void WINAPI _delete(CTest* Test)
  18. {
  19. delete Test;
  20. }
  21. }


 
 
Exe :

Code :
  1. class CTest
  2. {
  3. public:
  4. virtual void Membre()=0;
  5. };


 
le reste a peu pres comme tu fais

n°498518
chrisbk
-
Posté le 26-08-2003 à 14:22:53  profilanswer
 

+ oublie pas le . res de ta dll

n°498523
HelloWorld
Salut tout le monde!
Posté le 26-08-2003 à 14:26:22  profilanswer
 

Normal l'erreur, t'as pas défini ta methode.
Tente en spécifiant ta classe comme importée.
Je trouve que ton code commence à ressembler à une classe C++ utilisée à la C.
Pourquoi ne pas exporter une structure et des fonctions C et écrire un wrapper C++ ?
 
Sinon COM pour un plugin c'est bien oui. Mais c'est pas évident...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°498539
blackgodde​ss
vive le troll !
Posté le 26-08-2003 à 14:39:51  profilanswer
 

merci, ca marche impeccable.
 
par contre il va vraiment falloir que je me documente sur les méthodes virtuelles parce que je tatonne ...


---------------
-( BlackGoddess )-
n°498885
VisualC++
J'va y penser ...
Posté le 26-08-2003 à 19:28:17  profilanswer
 

Juste pour repondre a Gatorette, on peu si utilisation MFC (et AFXEXT) creer des DLL exportant des Class (pure ou pas).
Par contre jamais teste si Win32 pure.
 
Edit : BlackGoddess au fait pkoi LoadLibrary imperatif pour toi ?


Message édité par VisualC++ le 26-08-2003 à 19:28:51
n°499142
blackgodde​ss
vive le troll !
Posté le 26-08-2003 à 23:49:42  profilanswer
 

VisualC++
 
bien, si je fais mon plugin en dll (la méthode la moins contraignante je pense par rapport a la 2eme méthode : COM car il n'y a pas besoin d'enregistrer son plugin alors qu'avec COM d'apres ce que j'ai compris c'est obligatoire) il y a 2 méthodes pour la charger : l'inclure "en dur" au linkage, ou la charger avec LoadLibrary puis appeler ses fonctions avec GetProcAddress.
 
la méthode au linkage est à éliminer car je ne sais pas par avance le nom de mes plugins, leur nombre, etc. Reste donc la 2eme méthode.
 
Si tu vois une autre solution je suis preneur :)


---------------
-( BlackGoddess )-
n°499202
gatorette
Posté le 27-08-2003 à 01:16:03  profilanswer
 

VisualC++ a écrit :

Juste pour repondre a Gatorette, on peu si utilisation MFC (et AFXEXT) creer des DLL exportant des Class (pure ou pas).
Par contre jamais teste si Win32 pure.


 
Je ne connais pas ce type de DLL (j'utilise de moins en moins les MFCs maintenant que j'ai découvert la WTL) mais je ne pense pas que tu puisse lier ta bibliothèque de façon dynamique.
Et de façon statique, il est possible (avec Visual C++) d'exporter n'importe quelle classe MFC ou non (exception faite des classes avec templates).


---------------
each day I don't die is cheating
n°499208
gatorette
Posté le 27-08-2003 à 01:43:29  profilanswer
 

BlackGoddess a écrit :

...il n'y a pas besoin d'enregistrer son plugin alors qu'avec COM d'apres ce que j'ai compris c'est obligatoire...


 
Il est obligatoire d'enregistrer ses interfaces avec COM mais ce n'est pas très contraignant (quelques fonctions à implémenter qui sont créées automatiquement si tu utilises ATL ou que tu peux facilement adapter d'un exemple sinon). Mais l'avantage de COM est que tu n'as pas besoin de connaître le nom ou l'emplacement des DLLs.
COM a aussi l'avantage d'être la technologie utilisée par Microsoft pour avoir des "objets dynamiques". Les technologies récentes de Microsoft l'utilisent partout (Shell, DirectX...) et que beaucoup de gens connaissent et savent utiliser. De plus, c'est un système éprouvé et qui a dû demander pas mal de réflexion.
Il peut être intéressant de te pencher sur DirectShow et ses filtres. Le peu que j'en connaisse, c'est un système très riche. De plus, selon ton application, il peut être intéressant de pouvoir réutiliser les centaines (?), milliers (?) de filtres existants.
 
J'ai fait l'apologie de COM ici, mais c'est juste pour te montrer que la complexité n'est pas insurmontable et que c'est une technologie qui a certains avantages. Mais j'utilise pour le moment mon propre système que j'ai développé !
Une voie à explorer (si tu as le temps), c'est de regarder comment sont faits les API de logiciels communs utilisant des plug-ins (Winamp, 3DS-Max, Photoshop...).


---------------
each day I don't die is cheating
n°499210
chrisbk
-
Posté le 27-08-2003 à 01:54:04  profilanswer
 

3ds c'est comme j'ai expliqué : une DLL exportant des classes via une fonction de dll exporté (je suis hyper clair je sais)
 
Enfin, plus precisement :
 
la dll comprends deux fonctions :
->nombre de plugs in contenu
->fonction pour avoir une description du plug in n°i
 
la description donne le type du plug in (modifier, export...) et a aussi un fonction permettant la creation de l'objet plug in en lui meme. Ceux ci derivent tjs de classes de bases issu de 3dsmax (SimpleModifier....)
 
C'est relativement simple a faire, et assez efficace aussi

n°499588
Ashe2
Posté le 27-08-2003 à 13:56:12  profilanswer
 

Moi je fais comme ca :
 

Code :
  1. // A partager entre le code client et la dll
  2. class Interface
  3. {
  4. public:
  5.   virtual void Release() = 0;
  6.   virtual void Methode1() = 0;
  7.   virtual void Methode2() = 0;
  8. };
  9. // Dans la DLL
  10. class Implementation : public Interface
  11. {
  12. public:
  13.   Implementation() { }
  14.   ~Implementation() { }
  15.   void Release()
  16.   {
  17.     delete this;
  18.   }
  19.   void Methode1() { }
  20.   void Methode2() { }
  21. };
  22. extern "C" __declspec(dllexport) void CreerInstance( Interface *& blah )
  23. {
  24.   blah = new Implementation;
  25. }
  26. // Code client
  27. typedef void (* BLEH)( Interface *& );
  28. HMODULE hLib = LoadLibrary( "gnagna.dll" );
  29. BLEH fonction = reinterpret_cast<BLEH>(GetProcAddress( hLib, "CreerInstance" ));
  30. Interface * objet;
  31. fonction( objet );
  32. object->Methode1();
  33. object->Methode2();
  34. object->Release();

n°500101
blackgodde​ss
vive le troll !
Posté le 27-08-2003 à 23:59:17  profilanswer
 

c'etait la méthode abordée par chrisbk en plus développée, elle me plait beaucoup :)
 
je ne savais pas qu'il était possible de faire : delete this;
ca evite de devoir exporter une 2eme fonction :)
 
merci beaucoup :)


---------------
-( BlackGoddess )-
n°500130
gatorette
Posté le 28-08-2003 à 01:10:03  profilanswer
 

BlackGoddess a écrit :

je ne savais pas qu'il était possible de faire : delete this;
ca evite de devoir exporter une 2eme fonction :)


Il n'est pas impossible de faire des delete this; mais je trouve que cela devrait être évité à tout prix (et je ne suis pas le seul !).
Voici quelques articles sur le sujet ici ; et surtout celui-ci   qui présente pas mal de raisons de ne pas faire delete this.
 
--edit--
Correction d'un tag


Message édité par gatorette le 28-08-2003 à 01:10:47

---------------
each day I don't die is cheating
n°500235
blackgodde​ss
vive le troll !
Posté le 28-08-2003 à 09:22:56  profilanswer
 

mmh.
 
et si on fait :

Code :
  1. // Code client
  2.   typedef void (* BLEH)( Interface *& );
  3.  
  4.   HMODULE hLib = LoadLibrary( "gnagna.dll" );
  5.   BLEH fonction = reinterpret_cast<BLEH>(GetProcAddress( hLib, "CreerInstance" ));
  6.   Interface * objet;
  7.   fonction( objet );
  8.   object->Methode1();
  9.   object->Methode2();
  10.   delete object;


 
je suppose que c'est mauvais car le heap de l'executable et le heap de la dll n'est le meme ?


---------------
-( BlackGoddess )-
n°500246
gatorette
Posté le 28-08-2003 à 09:32:52  profilanswer
 

BlackGoddess a écrit :

je suppose que c'est mauvais car le heap de l'executable et le heap de la dll n'est le meme ?


 
Je ne sais pas trop sur ce point là, mais c'est de toute façon mauvais car tu n'es pas sûr de la façon dont ton objet a été créé.
 
Que se passe t'il si le plug-in se comporte comme ça :

Code :
  1. // variable globale
  2. Interface monObj;
  3. // fonction de création
  4. Interface * WINAPI CreerObjet()
  5. {
  6. return( &monObj );
  7. }


 
Ton application va planter au moment du delete ! Il me semble important de laisser la responsabilité de la création et de la destruction à la même personne.


---------------
each day I don't die is cheating
n°500269
HelloWorld
Salut tout le monde!
Posté le 28-08-2003 à 09:54:21  profilanswer
 

Citation :

je suppose que c'est mauvais car le heap de l'executable et le heap de la dll n'est le meme ?


 
Oui. C'est même pire que ça, car les lib standards peuvent être différentes ou de version différente (genre un prog BCB qui fait un delete sur un objet d'une dll VC++ ...).


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°500434
blackgodde​ss
vive le troll !
Posté le 28-08-2003 à 12:19:43  profilanswer
 

bien, encore merci pour ces précisions :)


---------------
-( BlackGoddess )-
n°500483
Ashe2
Posté le 28-08-2003 à 13:47:03  profilanswer
 

Il n'y a aucun problème a faire un delete this;, la méthode Release de COM fait la même chose.
De plus dans le logiciel qu'on développe pour le moment on a une 30aine d'interfaces créées de cette façon, ca n'a jamais planté, et c'est compilé avec 7 compilateurs différents sur 4 OS et 3 consoles...

n°500485
blackgodde​ss
vive le troll !
Posté le 28-08-2003 à 13:51:35  profilanswer
 

lool je prends note de la fiabilité évidente de cette méthode :)


---------------
-( BlackGoddess )-
n°500581
Ashe2
Posté le 28-08-2003 à 15:06:53  profilanswer
 

gatorette a écrit :


Que se passe t'il si le plug-in se comporte comme ça :

Code :
  1. // variable globale
  2. Interface monObj;
  3. // fonction de création
  4. Interface * WINAPI CreerObjet()
  5. {
  6. return( &monObj );
  7. }


 
Ton application va planter au moment du delete ! Il me semble important de laisser la responsabilité de la création et de la destruction à la même personne.


 
Une interface (ou une classe abstraite, pour parler en C++) ne peut pas être instanciée...
 

n°500658
gatorette
Posté le 28-08-2003 à 15:55:01  profilanswer
 

Ashe2 a écrit :


Une interface (ou une classe abstraite, pour parler en C++) ne peut pas être instanciée...


 
J'ai appelé abusivement ma classe Interface. Ce qui rend mon code peu compréhensible.
 
Code dans la DLL :

Code :
  1. class Interface
  2. {
  3. //
  4. // des fonctions purement virtuelles
  5. //
  6. };
  7. class MonPlugin : public Interface
  8. {
  9. //  
  10. // implémentation des fonctions d'Interface
  11. //
  12. }
  13. // variable globale  
  14. MonPlugin monObj;
  15. // fonction de création  
  16. Interface * WINAPI CreerObjet()
  17. {
  18. return( &monObj );
  19. }


 
J'espère que c'est plus clair.


---------------
each day I don't die is cheating
n°500708
Ashe2
Posté le 28-08-2003 à 16:28:48  profilanswer
 

Désolé, tt facon j'avais pas vu que tu parlais du code du plugin

mood
Publicité
Posté le   profilanswer
 


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

  (win32) classe dans une dll

 

Sujets relatifs
[Win32] Editeur de ressources .rc ?[python]classe + liste dans constructeur ??
[C Win32] Utilisation de la fonction CreateDialog()Win32 console application plus rapide qu'une application Windows
Membres d'une classe singletonRéférence à une fonction d'une autre classe
[C++] threads Win32Classe de lecture de fichier encodées - Approche Objet
[C++ Builder] Win32 Error. Code : 1410.La classe existe déjà[Win32 VisualC++] classe Win32 "SysDateTimePick32"
Plus de sujets relatifs à : (win32) classe dans une dll


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