Klassen in DLL und ihre Verwendung
-
Hallo erstmal,
als aller erstes:
Ich hoffe das Forum ist richtig, denn DLLs sind ja Windows-spezifisch.Also, ich habe gehört, dass man Klassen in DLLs nur indirekt nutzen kann.
Ich habe das jetzt so gereglt. Ich habe eine DLL OHNE die lib-Datei. D.h. ich muss die DLL über LoadLibrary laden. Soweit so gut. Eine Instanz der Klasse erzeuge ich über eine globale Funktion in der DLL, die eine Instanz zurück gibt (SCDAPI ist das übliche extern "C" __declspec (dllexport):SCDAPI CAnimal* GetAnimal(void) { return new CAnimal; } SCDAPI CRabbit* GetRabbit(void) { return new CRabbit; }
Die Klassen sind bekannt. In meiner Testapplikation ist die Implementation natürlich nicht bekannt. Lediglich die Klassendeklaration aus den Headerdateien ist bekannt.
Um das alles in der Testapplikation einfach zu halten habe ich zwei "API" Dateien erstellt:
Eine Header und eine CPP. Hier die Header:#pragma once #include <windows.h> #include "Animal.h" #include "Rabbit.h" namespace SimpleClassDLL { typedef CAnimal* (*ConvGetAnimal)(void); typedef CRabbit* (*ConvGetRabbit)(void); extern ConvGetAnimal GetAnimal; // "GetAnimal" aus der DLL extern ConvGetRabbit GetRabbit; // "GetRabbit" aus der DLL bool Startup(void); }
Und hier die CPP:
#include "SimpleClassDLL.h" namespace SimpleClassDLL { ConvGetAnimal GetAnimal = NULL; ConvGetRabbit GetRabbit = NULL; bool Startup(void) { HINSTANCE hDLL; hDLL = LoadLibrary("SimpleClassDLL.dll"); if (!hDLL) return false; GetAnimal = (ConvGetAnimal)GetProcAddress(hDLL, "GetAnimal"); if (!GetAnimal) return false; GetRabbit = (ConvGetRabbit)GetProcAddress(hDLL, "GetRabbit"); if (!GetRabbit) return false; return true; } }
Nach dem Ausruf von Startup sollte im Programm über die Funktionen eine Instanz erstellt werden:
CAnimal* pAnimal = GetRabbit();
Klappt auch wunderbar.
Jetzt zum eigentlichen Problem:
Der Konstruktor der Klassen ist bisher leer, was aber, wenn ich einen Konstruktor mit einer anderen Parameterliste aufrufen möchte?
Gibt es eine Möglichkeit mit derselben "Variable" (GetAnimal / GetRabbit) überladene Funktionen aufzurufen, oder muss ich dann GetAnimal2Parameters etc. anbieten (natürlich dann auch in der DLL)?Für eine kurze Antwort wäre ich dankbar.
MfG
plusman
-
Übergib doch die Parameter dem "GetRabbit".
IMHO wird es so aber auch nicht gehen. Spätestens wenn die Klassen mit virtuellen Methoden hast, geht es schief, da in Deinem Programm nicht bekannt ist, wie die virtuellen Methoden anzupsringen sind (es gibt da diverse Modelle: /vmm / vms /vmv)
Also ich kann nur davon abraten Klassen via LoadLibrary zu verwenden...
-
Also ich kann nur davon abraten Klassen via LoadLibrary zu verwenden...
Basiert nicht das Component Object Model auf Klassen in DLLs?
-
com schrieb:
Also ich kann nur davon abraten Klassen via LoadLibrary zu verwenden...
Basiert nicht das Component Object Model auf Klassen in DLLs?
So isses
-
Also, ich hab das jetzt soweit geregelt. Zum Thema mit virtuellen Methoden: Bei mir treten da keine Probleme auf.
Ich erzeuge ja eine Instanz
CAnimal* pAnimal = GetRabbit();
GetRabbit liefert ein CRabbit* Objekt! Das klappt.
ÜberpAnimal->Eat();
rufe ich die Methode CRabbit::Eat() auf! Da gibt es keine Probleme, klappt also auch ohne Probleme.
Mein eigentliches Problem habe ich jetzt über inline Funktionen geregelt, die einfach die Funktionen der DLL aufrufen, die jetzt allerdings, um Namenskonflikte zu vermeiden (Mit extern "C"... wird die Funktionssignatur ja bis auf den Namen gekürtzt) etwas kryptisch aussehen (z.B. GetRabbit_1P_string). Wenn man aber diese "API" hat, ist der Komfort im eigentliches Programm sehr hoch.
Falls ich das mit den virtuellen Methoden falsch verstanden habe, bitte aufklären
-
com schrieb:
Basiert nicht das Component Object Model auf Klassen in DLLs?
COM hat mit Klassen in DLLs nichts zu tun.
-
plusman schrieb:
Also, ich hab das jetzt soweit geregelt. Zum Thema mit virtuellen Methoden: Bei mir treten da keine Probleme auf.
Wenn bei Dir keine Probleme auftreten, heisst es noch lange nicht, das es nicht prinzipiell Problematisch ist.
-
Jochen Kalmbach schrieb:
com schrieb:
Basiert nicht das Component Object Model auf Klassen in DLLs?
COM hat mit Klassen in DLLs nichts zu tun.
Ok das COM ist ja nicht auf C++ beschränkt. Aber in C++ hat man halt Klassen in DLLs und da gibt es doch auch keine Probleme?!
-
com schrieb:
Aber in C++ hat man halt Klassen in DLLs und da gibt es doch auch keine Probleme?!
Natürlich gibt es da keine Probleme; aber nur wenn Du gegen die LIB linkst.
Mit COM hat das ganze aber nix zu tun.
-
Hm ich dachte dort wird in der Registry nachgeguckt und dann die passende DLL dynamisch per LoadLibrary geladen.
-
com schrieb:
Hm ich dachte dort wird in der Registry nachgeguckt und dann die passende DLL dynamisch per LoadLibrary geladen.
Aber in der DLL gibt es nur zwei C-Funktionen, welche von COM verwendet werden. Da gibt es direkt keine Klassen...
-
plusman hats doch aber auch so gemacht das er eine C-Funktion hat die dann die Objekte erstellt. Also die GetAnimal und GetRabbit sind doch eigentlich das gleiche wie DllGetClassObject. Ich sehe den Unterschied nicht.