Dies ist eine Fortsetzung der Kompilierung von Dynamic Shared Library mit g ++ .
Ich versuche, eine gemeinsam genutzte Klassenbibliothek in C ++ unter Linux zu erstellen. Ich kann die Bibliothek zum Kompilieren bringen und einige der (nicht klassenbezogenen) Funktionen mithilfe der Tutorials aufrufen, die ich hier und hier gefunden habe . Meine Probleme beginnen, wenn ich versuche, die in der Bibliothek definierten Klassen zu verwenden. Das zweite Tutorial, mit dem ich verlinkt habe, zeigt, wie die Symbole zum Erstellen von Objekten der in der Bibliothek definierten Klassen geladen werden, verwendet diese Objekte jedoch nicht mehr, um Arbeiten auszuführen.
Kennt jemand eine komplette Tutorial für Shared C ++ Klassenbibliotheken erstellen , die auch zeigt , wie man verwenden diese Klassen in einem separaten ausführbaren? Ein sehr einfaches Tutorial, das die Erstellung, Verwendung von Objekten (einfache Getter und Setter wären in Ordnung) und das Löschen zeigt, wäre fantastisch. Ein Link oder ein Verweis auf einen Open Source-Code, der die Verwendung einer gemeinsam genutzten Klassenbibliothek veranschaulicht, wäre ebenso gut.
Obwohl die Antworten von codelogic und nimrodm funktionieren, wollte ich nur hinzufügen, dass ich seit dieser Frage eine Kopie von Beginning Linux Programming aufgenommen habe. Das erste Kapitel enthält Beispiel-C-Code und gute Erklärungen zum Erstellen und Verwenden von statischen und gemeinsam genutzten Bibliotheken . Diese Beispiele sind über die Google Buchsuche in einer älteren Ausgabe dieses Buches verfügbar .
quelle
Antworten:
myclass.h
myclass.cc
class_user.cc
Kompilieren Sie unter Mac OS X mit:
Kompilieren Sie unter Linux mit:
Wenn dies für ein Plugin-System wäre, würden Sie MyClass als Basisklasse verwenden und alle erforderlichen Funktionen virtuell definieren. Der Plugin Autor würde dann von MyClass ableiten, überschreibt die virtuals und implementieren
create_object
unddestroy_object
. Ihre Hauptanwendung müsste in keiner Weise geändert werden.quelle
extern "C"
weil diedlsym
Funktion eine C-Funktion ist. Um diecreate_object
Funktion dynamisch zu laden , wird eine Verknüpfung im C-Stil verwendet. Wenn Sie das nicht verwenden würdenextern "C"
, gäbe es keine Möglichkeit, den Namen dercreate_object
Funktion in der .so-Datei zu kennen, da der Name im C ++ - Compiler geändert wurde.Das Folgende zeigt ein Beispiel für eine gemeinsam genutzte Klassenbibliothek, die gemeinsam genutzt wird. [H, cpp] und ein main.cpp-Modul, das die Bibliothek verwendet. Es ist ein sehr einfaches Beispiel und das Makefile könnte viel besser gemacht werden. Aber es funktioniert und kann Ihnen helfen:
shared.h definiert die Klasse:
shared.cpp definiert die getx / setx-Funktionen:
main.cpp verwendet die Klasse,
und das Makefile, das libshared.so generiert und main mit der gemeinsam genutzten Bibliothek verknüpft:
Um 'main' auszuführen und mit libshared.so zu verknüpfen, müssen Sie wahrscheinlich den Ladepfad angeben (oder ihn in / usr / local / lib oder ähnlichem ablegen).
Im Folgenden wird das aktuelle Verzeichnis als Suchpfad für Bibliotheken angegeben und main (Bash-Syntax) ausgeführt:
Um zu sehen, dass das Programm mit libshared.so verknüpft ist, können Sie ldd ausprobieren:
Druckt auf meinem Computer:
quelle
-L. -lshared -Wl,-rpath=$$(ORIGIN)
beim Verknüpfen und LöschenLD_LIBRARY_PATH=.
.Grundsätzlich sollten Sie die Header-Datei der Klasse in den Code aufnehmen, in dem Sie die Klasse in der gemeinsam genutzten Bibliothek verwenden möchten. Verwenden Sie dann beim Verknüpfen das Flag '-l' , um Ihren Code mit der gemeinsam genutzten Bibliothek zu verknüpfen. Dazu muss die .so natürlich dort sein, wo das Betriebssystem sie finden kann. Siehe 3.5. Installieren und Verwenden einer gemeinsam genutzten Bibliothek
Die Verwendung von dlsym ist gedacht, wenn Sie zur Kompilierungszeit nicht wissen, welche Bibliothek Sie verwenden möchten. Das hört sich hier nicht so an. Vielleicht besteht die Verwirrung darin, dass Windows die dynamisch geladenen Bibliotheken aufruft, unabhängig davon, ob Sie die Verknüpfung zur Kompilierung oder zur Laufzeit (mit analogen Methoden) durchführen. Wenn ja, können Sie sich dlsym als das Äquivalent von LoadLibrary vorstellen.
Wenn Sie die Bibliotheken wirklich dynamisch laden müssen (dh sie sind Plug-Ins), sollten diese FAQ helfen.
quelle
Zusätzlich zu den vorherigen Antworten möchte ich das Bewusstsein dafür schärfen, dass Sie die RAII-Sprache (Resource Acquisition Is Initialization) verwenden sollten, um die Zerstörung von Handlern sicher zu machen.
Hier ist ein vollständiges Arbeitsbeispiel:
Interface - Deklaration:
Interface.hpp
:Gemeinsamer Bibliotheksinhalt:
Dynamische Shared Library - Handler:
Derived_factory.hpp
:Kundencode:
Hinweis:
.hpp
und.cpp
Dateien aufteilen .new
/delete
Überladung behandeln möchten .Zwei übersichtliche Artikel, um weitere Details zu erhalten:
quelle