Ich habe Tage damit verbracht, alle Tutorials, die ich zu diesem Thema gefunden habe, zu lesen und wieder zu lesen, und ich habe Stunden (und sogar Tage) damit verbracht, verwandte Fragen hier bei SO zu durchstöbern, aber ich kann das Folgende immer noch nicht zum Laufen bringen. Bitte entschuldigen Sie, wenn dies ein Duplikat ist: Es kann sein, dass ich die doppelten Fragen schon oft gesehen und gelesen habe, aber die Relevanz der Antworten für mein Problem nicht verstehen konnte. Damit ist das Thema erledigt...
Ich versuche, eine Plugin-Architektur für meine Anwendung zu implementieren. Plugins werden kompiliert und als Bibliotheken installiert. Zur Laufzeit verwendet die Anwendung dann dlopen() / dlsym(), um die Funktionen des Plugins zu laden und zu verknüpfen.
Die Idee ist, dass Plugins (Bibliotheken) eine Reihe von Funktionen implementieren, um Daten an die Hauptanwendung zurückzugeben oder von der Anwendung übergebene Daten zu manipulieren.
Um diese Idee zu testen, habe ich versucht, eine Funktion (innerhalb des Plugins) zu implementieren, die den (für Menschen lesbaren) Namen des Plugins selbst (als std::string) zurückgibt. Ich dachte, das wäre etwas Einfaches für den Anfang.... :-/
Hier ist, was ich bis jetzt habe:
// Plugin.cpp
extern "C" void plugin_name(std::string *name) {
name = new std::string("Example plugin name");
}
// Application.cpp
void* handle = dlopen("libplugin.so", RTLD_LAZY);
typedef void (*plugin_t)(std::string*);
dlerror(); // Reset errors.
plugin_t call_plugin_name = (plugin_t) dlsym(handle, "plugin_name");
// ... Some error handling code.
std::string my_plugin_name;
call_plugin_name(&my_plugin_name);
dlclose(handle);
// More code that displays my_plugin_name.
Ich habe viele verschiedene Kombinationen ausprobiert, darunter eine, die einfacher zu sein schien (aber nicht besser funktionierte), bei der der Plugin-Name zurückgegeben wird:
// Plugin.cpp
extern "C" std::string plugin_name(void) {
return std::string("Example plugin name");
}
Ich weiß, dass ich nah dran bin: der Code kompiliert und die Anwendung stürzt nicht mehr ab ;)
An der Stelle, an der ich den eigentlichen Plugin-Namen erwarten würde, ist jedoch ein leeres Feld zu sehen.
Alle Tutorials, die ich bisher gelesen habe, gehen sehr schnell über den Mechanismus, mit dem Daten in beide Richtungen weitergegeben werden: Plugin <=> Anwendung. Was ich mit einem "einfachen" std::string zu tun versuche, möchte ich später mit viel komplexeren Objekten tun (d.h. eine Plugin-Funktion würde ein Objekt als Referenz nehmen und einige seiner Eigenschaften ändern). Die Tutorien hören mehr oder weniger alle an dem Punkt auf, an dem ein Zeiger mit dlsym() erzeugt wird, und geben nicht viele Beispiele dafür, wie man diesen Zeiger verwendet.
Wie kann man das alles machen?
Eine weitere relevante Frage: verwende ich eine gemeinsame Kopfzeile, die ich sowohl mit der Anwendung als auch mit dem Plugin verwenden würde und in der ich die Signatur der Funktionsaufrufe definieren würde? Wie würde ich das machen und wie würde das helfen?