Komplette Klassen in .lib einbinden?
-
Hallo.
Wie man Interfaces erstellt um ein Pluginsystem bereitzustellen habe ich mittlerweile gut verstanden; einziges Problem bleiben Klassen die man auch aus dem Plugin aus erstellen können soll.Mein einziger Ansatz wäre jetzt, die gesamte Klasse, also Header inklusive C++-Code, mitzuliefern, was ich jedoch nach Möglichkeit vermeiden möchte (aus diversen Gründen). Gibt es also die Möglichkeit, nur die Headerdateien zu liefern und die Implementation des C++-Codes in die .lib Datei zu verlagern?
Oder sollte ich das lieber anders regeln, in dem ich in meinem Programm z.B. eine Funktion erstelle, die
CreateClassXYheißt, und dann einen Pointer zurückliefert, der dem Header entspricht, den ich ausliefere?Gruß
-
Du meinst denke ich .dll und nicht .lib.
Das letzte is das was Du suchst. Du kannst eine DLL nur dynamisch laden ( was ja genau ein Plugin sein soll ) wenn Du einen eindeutigen Namen der Funktion hast die geladen werden soll. Und das geht nur mit extern C in C++, da dadurch Name Mangling verhindert wird.MyPlugin* plugin = NULL; void DllEntry() { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: plugin = new MyPlugin(); case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: delete plugin; } extern "C" MyPlugin* CreatePlugin() { return plugin; }So in die Richtung sollte das aussehen. Natürtlich muss der "Host Anwendung" das Aussehen der Klasse MyPlugin bekannt sein, damit Du es verwenden kannst. Hier empfiehlt sich eine Klasse die pure virtual funktionen enthält die das Plugin implementieren muss.
HTH
rya.
-
Hi.
Ja, genau so etwas meine ich.Das heißt, Klassen die direkt im Plugin instanzierbar und kopierbar sein sollen, MUSS ich komplett ausliefern, richtig?
Gruß
-
theliquidwave schrieb:
Hi.
Ja, genau so etwas meine ich.Das heißt, Klassen die direkt im Plugin instanzierbar und kopierbar sein sollen, MUSS ich komplett ausliefern, richtig?
Gruß
Ja. Irgendwo musst Du ja die Funktionen spezifizieren die eingesetzt werden können von der PluginKlasse. Am besten man erstellt ein enum mit Plugin-Typen, damit das Programm weiss, um was für eine art von plugin es sich handelt und was es überschreibt. Aber das kommt immer auf das Programm an wie man es organisiert und aufbaut.
rya.
-
http://www.fileuploadx.de/190145
Hab Dir hier mal ein Sample fix zusammengebastelt.
Ist halt Windows.Host.cpp:
#include <iostream> #include <windows.h> #include "../PluginInterface.hpp" #ifdef _DEBUG const std::wstring g_plugin_name = L"./Plugin1-d"; #else const std::wstring g_plugin_name = L"Plugin1"; #endif HINSTANCE g_dll_handle; typedef MyPluginInterface* (_cdecl CreatePluginProc)(); typedef void (_cdecl DestroyPluginProc)(); MyPluginInterface* LoadPlugin(LPCWSTR filename) { g_dll_handle = LoadLibrary(filename); if ( g_dll_handle != NULL ) { CreatePluginProc* CreatePlugin = (CreatePluginProc*)GetProcAddress(g_dll_handle, "CreatePlugin"); MyPluginInterface* plugin = CreatePlugin(); return plugin; } return NULL; } void FreePlugin() { if ( g_dll_handle != NULL ) { DestroyPluginProc* DestroyPlugin = (DestroyPluginProc*)GetProcAddress(g_dll_handle, "DestroyPlugin"); DestroyPlugin(); FreeLibrary(g_dll_handle); } } int main() { MyPluginInterface* plugin = NULL; plugin = LoadPlugin(g_plugin_name.c_str()); if ( plugin ) { plugin->print_message("Hello World"); FreePlugin(); return S_OK; } else { std::cout << "Cannot load plugin!" << std::endl; return E_FAIL; } }Plugin.cpp:
#include <iostream> #include <string> #include "../PluginInterface.hpp" #include <Windows.h> class MyPlugin : public MyPluginInterface { virtual void print_message(const std::string& msg) { std::cout << "[Plugin] " << msg << std::endl; } }; MyPlugin* g_plugin = NULL; int __stdcall DllMain(void * HDllHandle, unsigned reason, void * reserved) { switch(reason) { case DLL_THREAD_ATTACH: case DLL_PROCESS_ATTACH: { break; } case DLL_PROCESS_DETACH: case DLL_THREAD_DETACH: { break; } } return TRUE; } extern "C" __declspec(dllexport) MyPluginInterface* CreatePlugin() { g_plugin = new MyPlugin; return g_plugin; } extern "C" __declspec(dllexport) void DestroyPlugin() { delete g_plugin; }MyPluginInterface.h:
#ifndef PLUGININTERFACE_HPP #define PLUGININTERFACE_HPP #include <string> class MyPluginInterface { public: virtual void print_message(const std::string& msg) = 0; }; #endif // PLUGININTERFACE_HPPEinfaches Sample, aber funktioniert ;).
rya.
-
Cool, danke für das Beispiel, hilft mir schon weiter

Gute Nacht :>