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

  FORUM HardWare.fr
  Programmation
  C++

  DLL et destructeur de classes

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

DLL et destructeur de classes

n°962855
haazheel
Posté le 26-01-2005 à 15:50:25  profilanswer
 

Bonjour à tous,
 
voici mon problème (je suis sous BCB6 et la DLL est liée statiquement)
 
j'exporte la classe simplifiée suivante:
 

Code :
  1. //---------------------------------------------------------------------------
  2. #ifdef __DLL__
  3. #define IMPORT_EXPORT __declspec(dllexport)
  4. #else
  5. #define IMPORT_EXPORT __declspec(dllimport)
  6. #endif
  7. //---------------------------------------------------------------------------
  8. class IMPORT_EXPORT TVideoAffich
  9. {
  10. private:
  11.         boost::scoped_ptr<DS_Affich_Video> Affich_Video;
  12. public:
  13.         __fastcall DS_Affich_Video(HWND handle_fenetre, const WideString & path);     
  14.         __fastcall ~TVideoAffich();
  15. };


 
Voici maintenant la classe simplifiée DS_Affich_Video:
 

Code :
  1. class DS_Affich_Video : public DS_Graph
  2. {
  3. public:
  4. __fastcall DS_Affich_Video(HWND handle_fenetre, const WideString & path);
  5. __fastcall ~DS_Affich_Video()
  6. };


 
Et les classes dont dérive DS_Affich_Video:
 

Code :
  1. class DS_Base
  2. {
  3. public:
  4.         __fastcall DS_Base();
  5.         __fastcall ~DS_Base();
  6. };
  7. //---------------------------------------------------------------------------
  8. class DS_Graph : public DS_Base
  9. {
  10. public:
  11.         __fastcall DS_Graph();
  12.         __fastcall ~DS_Graph();
  13. };


 
Ma DLL se compile parfaitement bien.
 
Le problème vient du linker, qui me met:
 

[Lieur Erreur] Unresolved external '__fastcall DS_Affich_Video::~DS_Affich_Video()' referenced from D:\BORLAND\CBUILDER6\PROJECTS\TESTS PAQUETS\UNIT1.OBJ
 
[Lieur Erreur] Unresolved external '__fastcall TVideoAffich::~TVideoAffich()' referenced from D:\BORLAND\CBUILDER6\PROJECTS\TESTS PAQUETS\UNIT1.OBJ
 
[Lieur Erreur] Unresolved external '__fastcall DS_Base::~DS_Base()' referenced from D:\BORLAND\CBUILDER6\PROJECTS\TESTS PAQUETS\UNIT1.OBJ
 
[Lieur Erreur] Unresolved external '__fastcall DS_Graph::~DS_Graph()' referenced from D:\BORLAND\CBUILDER6\PROJECTS\TESTS PAQUETS\UNIT1.OBJ


 
Donc qu'il ne trouve pas les destructeurs des classes. Les destructeurs sont pourtant bien implémentés dans les .CPP et les CPP sont bien ajoutés dans le projet de la DLL.
 
Solutions:
1) Par contre si je mets les destructeurs directement dans le .H et que je recompile, tout se passe bien...
2) Egalement si je mets IMPORT_EXPORT pour les classes DS_Affich_Video, DS_Base et DS_Graph, ça compile correctement...
 
Je voudrais que l'on ne puisse importer que la première classe depuis la DLL. Je dois quand même utiliser la solution 2?
 
Merci d'avance!

mood
Publicité
Posté le 26-01-2005 à 15:50:25  profilanswer
 

n°962860
Joel F
Real men use unique_ptr
Posté le 26-01-2005 à 15:57:05  profilanswer
 

peut etre qu'avec des destructeurs virtuels ???

n°962925
haazheel
Posté le 26-01-2005 à 17:01:50  profilanswer
 

non, j'avais essayé, même en mettant les destructeurs de DS_Graph et DS_Base virtuels purs, ça donne rien.
 
Mais quand on utilise des classes pour la création d'une DLL, est-ce que toutes les classes doivent être préfixées IMPORT_EXPORT, ou bien seulement la classe que l'on veut utiliser?

n°962942
HelloWorld
Salut tout le monde!
Posté le 26-01-2005 à 17:21:05  profilanswer
 

Je suppose que c'est pour une utilisation de type factory (tu renvoie un TVideoAffich dont l'implémentation est cachée par la dll et peut varier selon X ou Y).
Ton problème c'est ta référence à DS_Affich_Video, qui est un détail interne.
Le plus propre c'est sûrement de le virer, un truc du genre:

Code :
  1. // interface exportée (classe abtraite)
  2. class IMPORT_EXPORT TVideoAffich
  3. {
  4. public:
  5.     static TVideoAffich * New();     
  6.     virtual __fastcall ~TVideoAffich() = 0; // rendre abstraite
  7. };
  8. // partie interne à la dll
  9. class TVideoAffichImpl : public TVideoAffich
  10. {
  11. private:
  12.         boost::scoped_ptr<DS_Affich_Video> Affich_Video;
  13. };
  14. TVideoAffich * TVideoAffich::New()
  15. {
  16.     return new TVideoAffichImpl;
  17. }


Mais tu peux faire plus simple:

Code :
  1. class IMPORT_EXPORT TVideoAffich
  2. {
  3. private:
  4.         // forward déclaration de DS_Affich_Video
  5.         boost::scoped_ptr<class DS_Affich_Video> Affich_Video;
  6. public:
  7.         __fastcall DS_Affich_Video(HWND handle_fenetre, const WideString & path);     
  8.         __fastcall ~TVideoAffich();
  9. };


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°962953
haazheel
Posté le 26-01-2005 à 17:33:40  profilanswer
 

HelloWorld a écrit :

Je suppose que c'est pour une utilisation de type factory (tu renvoie un TVideoAffich dont l'implémentation est cachée par la dll et peut varier selon X ou Y).
Ton problème c'est ta référence à DS_Affich_Video, qui est un détail interne.
Le plus propre c'est sûrement de le virer, un truc du genre:

Code :
  1. // interface exportée (classe abtraite)
  2. class IMPORT_EXPORT TVideoAffich
  3. {
  4. public:
  5.     static TVideoAffich * New();     
  6.     virtual __fastcall ~TVideoAffich() = 0; // rendre abstraite
  7. };
  8. // partie interne à la dll
  9. class TVideoAffichImpl : public TVideoAffich
  10. {
  11. private:
  12.         boost::scoped_ptr<DS_Affich_Video> Affich_Video;
  13. };
  14. TVideoAffich * TVideoAffich::New()
  15. {
  16.     return new TVideoAffichImpl;
  17. }



 
C'est un peu à la sauce COM ça non?
 

HelloWorld a écrit :

Mais tu peux faire plus simple:

Code :
  1. class IMPORT_EXPORT TVideoAffich
  2. {
  3. private:
  4.         // forward déclaration de DS_Affich_Video
  5.         boost::scoped_ptr<class DS_Affich_Video> Affich_Video;
  6. public:
  7.         __fastcall DS_Affich_Video(HWND handle_fenetre, const WideString & path);     
  8.         __fastcall ~TVideoAffich();
  9. };



 
Pourquoi ajouter "class" ici: boost::scoped_ptr<class DS_Affich_Video> Affich_Video;
 
Et peux-tu confirmer mon idée, selon laquelle uniquement les classes à exporter dans une DLL doivent avoir IMPORT_EXPORT, les autres étant des détails de l'implémentation?

n°962994
HelloWorld
Salut tout le monde!
Posté le 26-01-2005 à 18:18:22  profilanswer
 

Citation :

C'est un peu à la sauce COM ça non?


C'est peut être la notion d'interface qui te fait dire ça. C'est surtout le principe de la factory. Ici comme TVideoAffich est dérivée, son destructeur doit être virtuel. Et comme on veut forcer l'utilisation de la factory via New(), on la rend abstraite en rendant le destruteur virtuel pur.
 

Citation :

Pourquoi ajouter "class" ici: boost::scoped_ptr<class DS_Affich_Video> Affich_Video;  


ça revient à faire ça:

Code :
  1. // déclaration anticipée
  2. class DS_Affich_Video;
  3. class IMPORT_EXPORT TVideoAffich 
  4. private
  5.         // forward déclaration de DS_Affich_Video  
  6.         boost::scoped_ptr<DS_Affich_Video> Affich_Video; 
  7. public
  8.         __fastcall DS_Affich_Video(HWND handle_fenetre, const WideString & path);       
  9.         __fastcall ~TVideoAffich(); 
  10. };


sauf que là c'est fait direct dans le template.
La déclaration anticipée permet d'utiliser le type déclarer comme pointeur/référence, en gros:

Code :
  1. // déclaration anticipée
  2. class DS_Affich_Video;
  3. class IMPORT_EXPORT TVideoAffich 
  4. {
  5. public:
  6.     // ...  
  7. private
  8.     DS_Affich_Video * Affich_Video; // ça marche
  9. };


comme y'a eu forward declaration de DS_Affich_Video plus haut ça compile. Y'a plus qu'à include "DS_Affich_Video.h" dans le .cpp et c'est réglé. C'est une des techniques possibles pour accélérer la compilation en allégeant la liste des .h inclus (principe du pimpl : pprivate implementation). C'est aussi utile dans ton cas par exemple pour cacher des détails.
 

Citation :

Et peux-tu confirmer mon idée, selon laquelle uniquement les classes à exporter dans une DLL doivent avoir IMPORT_EXPORT, les autres étant des détails de l'implémentation?


Moui... c'est plutot dans l'autre sens : ce que tu veux exporter doit être marqué dllexport. Le problème c'est que là tu veux exporter la classe A qui repose sur la classe B, il te faut donc aussi exporter B sinon ça coince. Solution : faire que A ne repose plus sur B, ou exporter B aussi.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°963345
haazheel
Posté le 27-01-2005 à 03:59:23  profilanswer
 

Bon finalement j'ai choisi de créer des bibliothèques statiques plutôt que des DLL.
 
Néanmoins j'ai quelques questions:
 
soit A.lib, dans laquelle on a inclus file1.cpp
soit B.lib, dans laquelle on a inclus file2.cpp, et qui nécessite A.lib
 
soit final1.exe, qui nécessite A.lib
soit final2.exe, qui nécessite A.lib et B.lib
 
Pour final2.exe, je dois inclure au projet A.lib et B.lib ou bien uniquement B.lib (et à ce moment A.lib est ajouté au projet de B.lib)
 
J'espère que c'est clair :)
 
Deuxième question:
 
imaginons un fichier EXE pour lequel on doit inclure une dizaine de bibliothèques statiques. Est-ce obligatoire de renseigner le projet sur tous les chemins des .H utilisés par les bibliothèques?
 
Ex: A.lib a des types dont les déclarations se trouvent dans C:\types1\ et dans C:\Types2\.
 
final.exe, qui utilise A.lib, doit il lui aussi se coltiner les chemins des deux dossiers? Ou bien tout est-il inclus dans la bibliothèque, et je n'ai qu'à ajouter le .lib au projet?
 
Est-ce là la différence avec les DLL qui ne nécessitent pas toutes ces précisions (du moins en utilisation dynamique)?

n°963427
HelloWorld
Salut tout le monde!
Posté le 27-01-2005 à 10:05:27  profilanswer
 

D'après mon expérience, faut surtout pas ajouter de .lib à un .lib car si par malheur dans ton exe tu dois utiliser les 2 ou si une 3° lib utilise l'un des 2 tu as des symboles dupliqués. Donc tu files A.lib et B.lib a final.exe.
Une solution avec Visual C++ c'est d'avoir tes 3 projets (les 2 libs et l'exe) et simplement dans l'explorateur de solution, dans la gestion des dépendances de dire que l'exe dépend des 2 autres. Ca t'ajoutes les .lib au linkage, et ca recompile les .lib et relink l'exe si il le faut (modif d'une lib).
 
Normalement on ne spécifie pas les chemins dans le code source. Ca se règle aussi dans l'include path de ton compilateur. Tjrs sous VC++, typiquement, dans les propriétés de ton projet exe, tu va ajouter à "C/C++->Autres répertoires inclus" les chemin absolu ou relatif à tes 2 libs. Si tu as bien organisé ta solution, normalement ajouter "../A;../B" ça suffit (ou "../types1;../types2" dans ton cas).
C'est pas propre aux lib statiques, c'est le principe général de la compilation (include path, lib path).


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°963943
haazheel
Posté le 27-01-2005 à 18:34:53  profilanswer
 

HelloWorld a écrit :

Normalement on ne spécifie pas les chemins dans le code source. Ca se règle aussi dans l'include path de ton compilateur. Tjrs sous VC++, typiquement, dans les propriétés de ton projet exe, tu va ajouter à "C/C++->Autres répertoires inclus" les chemin absolu ou relatif à tes 2 libs. Si tu as bien organisé ta solution, normalement ajouter "../A;../B" ça suffit (ou "../types1;../types2" dans ton cas).
C'est pas propre aux lib statiques, c'est le principe général de la compilation (include path, lib path).


 
Le problème est que certaines de mes lib utilisent les même fichiers qui se trouvent dans un autre répertoire.
Ex: A.lib utilise toto.h dans ../divers, B.lib aussi mais en plus utilise foo.h dans ../autres
 
Donc pour l'EXE je dois spécifier à chaque fois tous les répertoires et c'est un peu gonflant...

n°963950
HelloWorld
Salut tout le monde!
Posté le 27-01-2005 à 18:41:44  profilanswer
 

A toi de voir ce qui est le + gonflant entre mettre le path 1 fois dans les settings projet ou a chaque fois dans les #include.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
mood
Publicité
Posté le 27-01-2005 à 18:41:44  profilanswer
 

n°968687
haazheel
Posté le 01-02-2005 à 19:05:11  profilanswer
 

Encore une question:
 
comment instancier une classe quand la DLL est chargée dynamiquement? Pour une fonction, c'est pas dur c'est avec GetProcAddress.
 
Est-ce que je dois créer une fonction retournant une instance de la classe?
Et une autre se chargeant de la détruire, car je pense que création et destruction doivent se faire sur le même lieu d'appel (ici dans la DLL)?

n°968702
haazheel
Posté le 01-02-2005 à 19:33:51  profilanswer
 

J'ai fait ceci, qui a l'air de fonctionner, mais qui a l'air de provoquer une fuite mémoire (sur base des classes que j'ai mentionné plus haut):
 
DLL
 

Code :
  1. int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
  2. {
  3.         return 1;
  4. }
  5. namespace
  6. {
  7. TVideoAffich * Video;
  8. }
  9. //---------------------------------------------------------------------------
  10. extern "C" __declspec(dllexport) TVideoAffich * __stdcall Create_Video_Affich(TComponent* Owner, HWND hwnd)
  11. {
  12. Video = TVideoAffich::Create_From_Null(Owner,hwnd);
  13. return Video;
  14. }
  15. //---------------------------------------------------------------------------
  16. extern "C" __declspec(dllexport) void __stdcall Delete_Video_Affich()
  17. {
  18. delete Video;
  19. Video = NULL;
  20. }


 
Utilisation

Code :
  1. namespace
  2. {
  3. typedef TVideoAffich* (__stdcall *MYDLLFUNC) (TComponent* Owner, HWND hwnd);
  4. typedef void* (__stdcall *MYDLLFUNC2) ();
  5. MYDLLFUNC ImpFuncDLL;
  6. MYDLLFUNC2 ImpFuncDLL2;
  7. }
  8. //---------------------------------------------------------------------------
  9. __fastcall TForm1::TForm1(TComponent* Owner)
  10. : TForm(Owner)
  11. {
  12. CoInitialize(NULL);
  13. hinstDLL = LoadLibrary("Video_Affichage.dll" );
  14. }
  15. //---------------------------------------------------------------------------
  16. void __fastcall TForm1::Button1Click(TObject *Sender)
  17. {
  18. ImpFuncDLL = (MYDLLFUNC)GetProcAddress(hinstDLL, "Create_Video_Affich" );
  19. if (ImpFuncDLL)
  20. {
  21.         TVideoAffich * Video = ImpFuncDLL(this,Application->Handle);
  22.         Video->Show();
  23. }
  24. }
  25. //---------------------------------------------------------------------------
  26. void __fastcall TForm1::FormDestroy(TObject *Sender)
  27. {
  28. ImpFuncDLL2 = (MYDLLFUNC2)GetProcAddress(hinstDLL, "Delete_Video_Affich" );
  29. if (ImpFuncDLL2)
  30.         ImpFuncDLL2();
  31. FreeLibrary(hinstDLL);
  32. CoUninitialize();
  33. }
  34. //---------------------------------------------------------------------------


 
Je suis obligé de faire comme ça?
Est-ce que je suis obligé de détruire l'instance de TVideoAffich dans la DLL?
N'existe-il pas une librairie permettant de simplifier tout ça?
 
Merci d'avance

n°968913
HelloWorld
Salut tout le monde!
Posté le 02-02-2005 à 01:21:25  profilanswer
 

Il faut que tes dll partagent la même CRT (lib standard) sinon va y avoir probleme (chaque dll aura sa propre gestion des new/delete). A part ça new/delete sur une classe importée statiquement ça devrait marcher.
Après pour simplifier, je sais pas si c'est le bon terme, mais on va vite songer à COM, qui est une usine à gaz spécialisée dans la communication entre composants logiciels objets. Mais bon ça se mérite : c'est assez coton.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°968917
haazheel
Posté le 02-02-2005 à 02:23:37  profilanswer
 

Mon problème, et je pense que tu l'as bien compris, est que mes Dlls ne servent juste qu'à "stocker" mes classes communes à mes différents projets. Là je tentais de les utiliser dynamiquement à cause d'autres problèmes dus à BCB6.
 
Ce que je veux juste, c'est pouvoir utiliser mes classes comme si je les avais bien incluses dans mon projet, et c'est tout. C'est pour cela que je pense revenir vers des .lib tout simple.
 
Sinon concernant COM, je l'utilise déjà je pense à travers DirectShow, et les librairies ATL. Mais je ne sais qu'utiliser les classes déjà présentes à coup de QueryInterface et compagnie.
 
Je ne sais pas du tout comment créer un client COM (parce que c'est bien de ça dont il s'agit non?)
 
Aurais-tu des liens là dessus en cette fin de soirée?
 
Merci en tout cas pour tes réponses.

n°969016
HelloWorld
Salut tout le monde!
Posté le 02-02-2005 à 10:38:38  profilanswer
 

Créer un .lib ou une dll, si c'est linké en static, pas de problème à priori, sauf pour la dll ou il faut veiller à partager la lib standard (option de compilation). Mais ça marche très bien ensuite, y'a plein de dll qui font ça. Au hasard Qt : des dizaines et des dizaines de classes toutes importées (statiquement) depuis une dll. Idem les MFC, et plein d'autre exemples...
Pour COM, c'est plutot un serveur que tu doit créer. Utiliser un composant COM ça peut être plus ou moins facile selon le langage. Créer un composant c'est forcément plus dur, et j'ai pas d'expérience dans ce domaine (je me suis jamais plongé dans ATL). Si tu cherches juste à découper ton programme mettre dans une dll ou lib statique c'est très bien. COM devient intéressant quand cette dll doit être utilisée depuis plusieurs applis / langages, ou dès que y'a un binding dynamique de classe (plugin, ...).
Une FAQ intéressante sur COM:
http://www.developpez.com/windows/dcom/t1.html


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°969256
haazheel
Posté le 02-02-2005 à 12:56:51  profilanswer
 

Effectivement partager des classes comme ça, c'est vraiment pas mal, notamment pour les mises à jour.
 
Mais j'ai une erreur qui me chiffonne quand j'utilise les DLL, c'est le gestionnaire mémoire. En effet j'ai quelques classes singleton qui sont utilisées dans les différentes DLL et dans mon programme (une classe d'options, une classe Language pour les versions traduites du soft...) et chaque classe qui l'utilise récupère l'instance du singleton. Le problème est que CodeGuard (une sorte de vérificateur de fuites mémoire) m'indique une fuite pour chaque instance d'un singleton dans chaque DLL qui l'a utilisé... Alors je suis obligé de détruire le singleton dans chaque sortie de DLL, ce qui ne convient pas du tout.
 
Donc pour l'instant je suis obligé de passer par des libs...

n°969984
HelloWorld
Salut tout le monde!
Posté le 02-02-2005 à 22:29:47  profilanswer
 

Si tu link en static la dll t'as pas à gérer le DllMain normalement.
Tu l'as fait comment ton singleton ? Typiquement:

Code :
  1. Singleton * Singleton::GetInstance()
  2. {
  3.     static Singleton instance;
  4.     return &instance;
  5. }


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°970199
haazheel
Posté le 03-02-2005 à 04:20:00  profilanswer
 

Code :
  1. template <class T>
  2. class Singleton
  3. {
  4. public :
  5.         static T* getInstance()
  6.         {
  7.         if (!instance) instance = new T;
  8.         return instance;
  9.         }
  10.         static void Release()
  11.         {
  12.         if (instance) delete instance;
  13.         instance = NULL;
  14.         }
  15. protected :
  16.         Singleton() {}
  17.         ~Singleton() {}
  18. private :
  19.         static T* instance;
  20.         Singleton(Singleton& );
  21.         void operator =(Singleton& );
  22. };
  23. template <class T> T* Singleton<T>::instance = NULL;


 
ET je l'utilise comme suit:
 

Code :
  1. class Gestion_BDD : public Singleton<Gestion_BDD>
  2. {
  3. private:
  4.         friend Singleton<Gestion_BDD>;
  5.         __fastcall Gestion_BDD();
  6.         __fastcall ~Gestion_BDD();
  7. public:
  8. };


 
Je confirme le problème... Là où avant je faisais ClasseX::Release(); à la fin de l'exécution de l'EXE (normal quoi) je dois le faire pour chaque destructeur des classes appellées dans mes DLL.
 
Là j'ai recompilé mes DLL en librairies statiques, et plus aucun souci...

n°970224
HelloWorld
Salut tout le monde!
Posté le 03-02-2005 à 09:55:44  profilanswer
 

Ah ben oui si ton Singleton doit être libéré c'est pas top. Pourquoi tu utilises pas un objet statique automatique (c.f mon exemple) au lieu d'un objet alloué dynamiquement ?
Avec une lib statique ton Release sera jamais appelé. Et à quoi setr le

Code :
  1. friend Singleton<Gestion_BDD>;

?
Et pourquoi tu pourris ton code de __fastcall ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°971173
haazheel
Posté le 04-02-2005 à 00:15:23  profilanswer
 

HelloWorld a écrit :

Ah ben oui si ton Singleton doit être libéré c'est pas top. Pourquoi tu utilises pas un objet statique automatique (c.f mon exemple) au lieu d'un objet alloué dynamiquement ?
Avec une lib statique ton Release sera jamais appelé. Et à quoi setr le

Code :
  1. friend Singleton<Gestion_BDD>;

?
Et pourquoi tu pourris ton code de __fastcall ?


 
Cet exemple?
 

Code :
  1. Singleton * Singleton::GetInstance()
  2. {
  3. static Singleton instance;
  4. return &instance;
  5. }


 
Je ne sais pas, j'ai toujours utilisé ce code... Je n'ai jamais pensé à le changer...
 

Code :
  1. friend Singleton<Gestion_BDD>;

c'est parce que Gestion_BDD dérive d'un template, donc il faut une instanciation, qui est protected dans le template, d'où le friend pour que Gestion_BDD puisse y accéder. C'est mieux expliqué ici http://loulou.developpez.com/tutor [...] tie1/#L3.4
C'est là que j'ai choppé l'exemple...
 
Et enfin les __fastcall, c'est pour BCB6. Voici ce que dit la doc:

Description
 
Le modificateur __fastcall permet de déclarer des fonctions attendant que des paramètres soient transmis dans les registres. Les trois premiers paramètres sont transmis (depuis la gauche vers la droite) dans EAX, EDX et dans ECX, s'ils rentrent dans le registre. Les registres ne sont pas utilisés si le paramètre est de type virgule flottante ou structure.


 
Et ils conseillent de l'utiliser partout...
 
Voilà :)

n°971182
HelloWorld
Salut tout le monde!
Posté le 04-02-2005 à 00:29:12  profilanswer
 

__fastcall c'est un bon moyen de rendre le code non portable (tout ce qui commence par un ou deux underscore est à éviter). En général au lieu de faire ça partout tu as une option de ton compilateur pour changer la convention par défaut.
Pour le friend oui j'ai compris après coup. C'est un implémentation possible du singleton, moi j'aime moyen mais bon ça marche. Pour un vrai singleton avec une seule instance, je préfère l'objet statique, t'as pas à gérer sa création / désallocation.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°971425
haazheel
Posté le 04-02-2005 à 11:47:36  profilanswer
 

A quoi ressemble la classe complète alors?

n°972434
HelloWorld
Salut tout le monde!
Posté le 04-02-2005 à 23:34:42  profilanswer
 
n°972542
haazheel
Posté le 05-02-2005 à 00:22:56  profilanswer
 

J'vais jeter un oeil, merci

mood
Publicité
Posté le   profilanswer
 


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

  DLL et destructeur de classes

 

Sujets relatifs
debuggage d'une DLL sous visual studio.net C++VB.NET classes et tableaux de classes
[UML] diagramme des classes et linuxUtilisation d'une DLL dans Java
exporter des instances de classes d'une DllDLL en ressource avec Devcpp
Export de fonctions EXE -> DLL et DLL -> EXE[Axis - Web Service - newbe] Utiliser des objets d'autre classes...
destructeur 
Plus de sujets relatifs à : DLL et destructeur de classes


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