C++ Dynamique de Bibliothèque Partagée sur Linux
C'est un suivi à Dynamique Partagée de la Bibliothèque de la compilation avec g++.
Je suis en train de créer une classe partagée de la bibliothèque en C++ sur Linux. Je suis en mesure d'obtenir à la bibliothèque de la compilation, et je peux les appeler de la (non-classe) de fonctions en utilisant les tutoriels que j'ai trouvé ici et ici. Mes problèmes commencent lorsque j'essaie d'utiliser les classes qui sont définies dans la bibliothèque. Le deuxième tutoriel que j'ai liée montre comment charger les symboles pour créer des objets, des classes définies dans la bibliothèque, mais s'arrête de à l'aide de ces objets pour obtenir le travail fait.
Personne ne sait de plus tutoriel complet pour la création partagée bibliothèques de classe C++ qui montre également comment utilisation ces classes dans un exécutable séparé? Un très simple tutoriel qui montre la création de l'objet, de l'utilisation (simple getters et setters serait bien), et la suppression serait fantastique. Un lien ou une référence à un code open source qui illustre l'utilisation d'une bibliothèque de classe serait tout aussi bon.
Bien que les réponses de codelogic et nimrodm faire un travail, je voulais juste ajouter que j'ai ramassé une copie de Début De Linux Programmation depuis posant cette question, et son premier chapitre a exemple de code C et de bonnes explications pour la création et l'utilisation à la fois statiques et des bibliothèques partagées. Ces exemples sont disponibles par le biais de Google Recherche de livres dans une édition plus ancienne de ce livre.
- Je ne suis pas sûr de comprendre ce que vous entendez par "utilisation", une fois un pointeur vers l'objet est retourné, vous pouvez l'utiliser comme vous utilisez tout autre pointeur vers un objet.
- L'article que j'ai lié à montre comment créer un pointeur de fonction à un objet de l'usine de la fonction en utilisant dlsym. Il ne montre pas la syntaxe pour la création et l'utilisation des objets de la bibliothèque.
- Vous aurez besoin du fichier d'en-tête décrivant la classe. Pourquoi pensez-vous que vous devez utiliser le "dlsym" au lieu de laisser l'OS de trouver et de lier la bibliothèque au moment du chargement? Laissez-moi savoir si vous avez besoin d'un exemple simple.
- Quelle est l'alternative à l'utilisation de "dlsym"? Je suis (censé être) écrit 3 programmes C++ qui utilisent toutes les classes définies dans la bibliothèque partagée. J'ai aussi 1 script Perl qui va l'utiliser, mais c'est un tout autre problème pour la semaine prochaine.
Vous devez vous connecter pour publier un commentaire.
myclass.h
myclass.cc
class_user.cc
Sur Mac OS X, compiler avec:
Sur Linux, compiler avec:
Si c'était pour un système de plugin, vous pouvez utiliser MyClass comme une classe de base et de définir toutes les fonctions nécessaires virtuel. L'auteur du plugin serait alors de dériver à partir de Maclasse, remplacer les virtuals et de mettre en œuvre
create_object
etdestroy_object
. Votre application principale n'aurait pas besoin d'être modifié en aucune façon.extern "C"
parce que ledlsym
fonction est une fonction C. Et de charger dynamiquement lecreate_object
fonction, utilisez C-style de couplage. Si vous n'utilisez pas leextern "C"
, il n'y aurait aucun moyen de savoir le nom de lacreate_object
fonction dans les .donc, fichier, parce que de nom-déformation dans le compilateur C++.MyClass* myClass = (MyClass*)create();
n'est pas nécessaire (ou plus). Un peu étrange qu'aucun des précédents 49K téléspectateurs remarqué 🙂 Ou je me trompe? Aussi, ne serait-il pas agréable de soupçon les lecteurs sur pourquoi le code du client ne sera même pas le lien s'il avait essayé d'appeler le constructeur, tout en appelant un virtual la fonction est ok (la réponse de préciser le cryptiques-à la recherche de commentaires sur linker les goûts :))?dlclose
sur la poignée. S'il vous plaît ajouter que.-fPIC
nécessaire?destroy_object
fonction nécessaire? Peut-on seulement appelerdelete myClass
dansmain
?La figure suivante montre un exemple d'une classe partagée la bibliothèque partagée.[h,rpc] et un main.cpp module à l'aide de la bibliothèque. C'est un exemple très simple et le makefile pourrait être beaucoup mieux. Mais il fonctionne et peut vous aider à:
partagé.h définit la classe:
shared.cpp définit la getx/setx fonctions:
main.cpp utilise la classe,
et le fichier makefile qui génère libshared.donc, et les liens principaux avec la bibliothèque partagée:
À l'exécution réelle "principal" et le lien avec libshared.donc vous aurez probablement besoin de spécifier le chemin de chargement (ou de le mettre dans /usr/local/lib ou similaire).
Le suivant spécifie le répertoire courant comme le chemin de recherche pour les bibliothèques et les pistes principales (bash syntaxe):
De voir que le programme est lié avec libshared.ainsi, vous pouvez essayer la commande ldd:
Imprime sur ma machine:
-L. -lshared -Wl,-rpath=$$(ORIGIN)
lors de la liaison et deLD_LIBRARY_PATH=.
.Fondamentalement, vous devez inclure le fichier d'en-tête dans le code où vous souhaitez utiliser la classe dans la bibliothèque partagée. Puis, quand vous faites le lien, utilisez l'option '-l' drapeau de lier votre code avec la bibliothèque partagée. Bien sûr, cela nécessite l' .donc, pour être là où le système d'exploitation peut le trouver. Voir 3.5. L'installation et l'Utilisation d'une Bibliothèque Partagée
À l'aide de dlsym est pour quand on ne sait pas au moment de la compilation de la bibliothèque que vous souhaitez utiliser. Ce n'est pas, comme c'est le cas ici. Peut-être que la confusion est que Windows appelle les bibliothèques chargées dynamiquement si vous ne le reliant à la compilation ou de l'exécution (avec des analogues méthodes)? Si oui, alors vous pouvez penser de dlsym comme l'équivalent de la fonction LoadLibrary.
Si vous avez vraiment besoin de charger dynamiquement les bibliothèques (c'est à dire, ils sont des plugins), puis cette FAQ devrait aider.
Sur le dessus de réponses précédentes, je tiens à sensibiliser la population au fait que vous devez utiliser le RAII (Acquisition de Ressources Est d'Initialisation) idiom pour être sûr de gestionnaire de destruction.
Ici est un exemple de travail:
Déclaration d'Interface:
Interface.hpp
:Partagé le contenu de la bibliothèque:
Dynamique partagée de la bibliothèque de gestionnaire:
Derived_factory.hpp
:Code Client:
Remarque:
.hpp
et.cpp
fichiers.new
/delete
surcharge.Deux articles pour obtenir plus de détails: