Klassen aus DLL exportieren, bzw wie in GUI laden.
-
Hallo Forum,
ich habe ein Programm mit vielen Klassen. Manche Klassen funktionieren nicht wenn ein älteres OS als Win2000 eingesetzt wird. Ich möchte nun mein großes Projekt in ein kleines MFC C++ Gui Projekt aufteilen und die Funktionalität in 2 DLL Projekte verschieben. Das ein DLL Projekt ist für Win2000 und neuere Betriebssyteme und eines für Win95. Beide DLLs werden mit ausgeliefert; die GUI ermittelt das OS und läd dann die richtige DLL.
Meine Fragen:
1. Wie lade ich die Klassen aus der DLL in meine MFC Gui? Bei Loadlibrary muß ich doch ein C Interface für meine Klassen schreiben? Kann ich nicht irgendwie die Klassen exportieren? (Ich muß dynamisch laden, kann also keine statische Lib benutzen.) Es sollte ein einfacher Weg sein, weil ich bisher nur C programmiert habe.Hier mein Versuch eine Test Klasse in eine Test DLL zu verschieben
#ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport) #else #define TESTDLL_API __declspec(dllimport) #endif class TESTDLL_API CTESTDll { public: CTESTDll(); ~CTESTDll(); Start(); // Füllt m_wsOutput mit einem Teststring. std::wstring GetString(); // Gibt m_wsOutput zurück. private: std::wstring m_wsOutput; // Interne Daten. Diese Zeile wird angemeckert. };Beim Kompilieren bekomme ich diese Fehlermeldungen:
t:\vs6\testdll\testdll.h(22) : warning C4251: 'm_wsOutput' : class 'std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> >' needs to have dll-interface to be used by clients of class 'CTESTDll'
Was ist mit dll-interface gemeint? Ich dachte der obige Auschnitt aus meinem Header File wäre das? (Wenn ich aber Loadlibrary benutzen muß erübrigt sich die Frage.)
-
Das Schweigen interpretiere ich jetzt so das ich jetzt einen C Funktionswrapper für meine Klassen schreiben muß. Das man Klassen nur mit Libs statisch einbinden kann.
-
Der einfachste mir bekannte Weg ist genau eine Funktion zu exportieren, die dir eine Factory mit lauter virtual pure Members zurückliefert. Also ca. so:
class Factory { public: virtual A* CreateA() = 0; virtual B* CreateB() = 0; // ... virtual void ~Factory() = 0; }; extern "C" Factory* __declspec(dllexport) GetFactory();Alle Klassen die du da rausreichst (A, B, ... und Factory, alle!) bestehen einzig aus virtual pure Funktionen. Und die Header Files in denen diese Klassen definiert sind müssen für beide DLLs genau gleich sein (am besten verwendest du die selben Files für beide DLLs, dann kann fast nix schief gehen).
Ferdich.Wenn du in deiner Applikation drinnen nicht mit den ganzen "CreateX()" Aufrufen arbeiten willst kannst du es ja immernoch in der Applikation "pimpln", also so:
Factory* g_fac = 0; // wird von WinMain/InitInstance oder so "befüllt" class WrapA { public: WrapA() : m_pimpl(g_fac->CreateA()) { if (!m_pimpl) throw blubb(); } ~WrapA() { delete m_pimpl; } int Foo(std::string const& x) { return m_pimpl->Foo(x); } // ... private: A* m_pimpl; }Oder du installierst einfach nur die passende DLL, die andere kommt garnicht auf das Zielsystem. Dann kannst du statich linken. Die Headerfiles müssen natürlich trotzdem gleich sein zwischen den beiden DLLs, bloss dann kannst du dir den ganzen Factory-Zirkus sparen. Und die "nur virtual pure" Beschränkung fällt damit weg.
Eigentlich alles ganz einfach.
-
BTW: nichtmal 2 Stunden zu warten und dann "das Schweigen zu interpretieren" ist wohl der Gipfel der Lächerlichkeit. Noch dazu zu Mittag... hallo, Mittagspause irgendwer? Nächstens erwartest du noch dass das Forum dir gleich beim Druch auf "Absenden" ein Fenster mit 10 Antworten aufmacht...
