2009-01-26 13 views
18

Ich schreibe Code, der dynamische DLLs als Plugins verwendet.Fehlermeldung "undefined symbol" beim Laden der Bibliothek mit dlopen empfangen

Meine Kommandozeile die gemeinsamen Bibliotheken für den Bau wie folgt aussieht:

cc -shared -fPIC -o module.so -g -Wall module.c 

Innerhalb des Moduls kann ich Funktionen aufrufen, die in jedem anderen gemeinsam genutzten Bibliothek, die im Hauptprogramm geladen wurde.

Allerdings kann ich nicht auf (exportierte) Funktionen zugreifen, die in der ausführbaren Datei selbst sind (ich bekomme undefined symbol Fehler).

Mein Aufruf an dlopen sieht wie folgt aus:

void *handle = dlopen(plugin, RTLD_NOW); 

Kann jemand bitte beraten, wie kann mein Modul meine ausführbare Datei zurückrufen, ohne dass alle ausführbaren Datei der Utility-Funktionen in eine weitere gemeinsame Bibliothek setzen zu müssen?

Antwort

5

Ich habe die Antwort selbst gefunden.

Ich musste die --export-dynamic Flags zu den Link-Optionen für die Hauptdatei hinzufügen.

Beim Erstellen eines dynamisch ausführbaren verknüpft, alle Symbole in die Tabelle dynamischen Symbols hinzuzufügen. Die dynamische Symboltabelle ist die Menge der Symbole , die zur Laufzeit von dynamischen Objekten sichtbar sind.

Wenn Sie diese Option nicht verwenden, die dynamische Symboltabelle enthält normalerweise nur die Symbole, die durch ein dynamisches Objekt referenziert sind in der Verbindung erwähnt.

Wenn Sie „dlopen“ verwenden, um ein dynamisches Objekt zu laden, die die Symbole zurück zu nachschlagen muss durch das Programm definiert, anstatt ein anderes dynamisches Objekt, dann müssen Sie wahrscheinlich diese Option verwenden, wenn Verknüpfung des Programms selbst.

29

Korrekte Lösung istzum Link-Befehl der Hauptdatei hinzuzufügen. Dies wird die passende Option zu ld hinzufügen (was, wenn GNU ld verwendet wird, zufällig --export-dynamic ist).

Das direkte Hinzufügen von --export-dynamic ist technisch falsch: es ist eine Linker-Option und sollte daher als -Wl,--export-dynamic oder -Wl,-E hinzugefügt werden. Dies ist auch weniger portabel als (andere Linker haben ein Äquivalent, aber die Option selbst ist anders).

+0

Diese Lösung gilt auch, wenn Boost-Erweiterungen verwendet werden, da die Klasse shared_library dlopen (unter Linux) zum Laden der Bibliothek verwendet. –

4

Als ich auf das gleiche Problem stieß, habe ich nur die folgende Lösung verwendet. Vor jeder Plugin laden, laden Sie einfach das Programm selbst, seine Symbole zu dynamischen Tabellen bringen:

dlopen(NULL,RTLD_NOW|RTLD_GLOBAL); 

ich glaube, die Lösung ist besser.Der Grund ist, dass es auch das gleiche Problem löst, wenn Sie

a) Ihr Programm (oder ein trird-Party-Modul) ist verknüpft (nicht in der Laufzeit) gegen die gemeinsame Bibliothek, die Symbole in dynamische Tabelle sein müssen;

b) kann dieses Modul nicht mit dem Flag -dynamic neu kompilieren.

Verwandte Themen