Il s'agit d'un suivi de la compilation Dynamic Shared Library avec g ++ .
J'essaye de créer une bibliothèque de classes partagée en C ++ sur Linux. Je suis capable de faire compiler la bibliothèque, et je peux appeler certaines des fonctions (hors classe) en utilisant les didacticiels que j'ai trouvés ici et ici . Mes problèmes commencent lorsque j'essaye d'utiliser les classes définies dans la bibliothèque. Le deuxième tutoriel auquel j'ai lié montre comment charger les symboles pour créer des objets des classes définies dans la bibliothèque, mais s'arrête avant d' utiliser ces objets pour effectuer le travail.
Quelqu'un connaît-il un didacticiel plus complet pour créer des bibliothèques de classes C ++ partagées qui montre également comment utiliser ces classes dans un exécutable distinct? Un didacticiel très simple qui montre la création d'objets, leur utilisation (de simples getters et setters conviendraient) et leur suppression serait fantastique. Un lien ou une référence à un code open source qui illustre l'utilisation d'une bibliothèque de classes partagée serait tout aussi bien.
Bien que les réponses de codelogic et nimrodm fonctionnent, je voulais juste ajouter que j'ai pris une copie de Beginning Linux Programming depuis que j'ai posé cette question, et son premier chapitre contient un exemple de code C et de bonnes explications pour créer et utiliser des bibliothèques statiques et partagées. . Ces exemples sont disponibles via Google Recherche de Livres dans une ancienne édition de ce livre .
la source
Réponses:
myclass.h
myclass.cc
class_user.cc
Sous Mac OS X, compilez avec:
Sous Linux, compilez avec:
S'il s'agissait d'un système de plugins, vous utiliseriez MyClass comme classe de base et définiriez toutes les fonctions requises virtuelles. L'auteur du plugin dériverait alors de MyClass, remplacerait les virtuels et implémenterait
create_object
etdestroy_object
. Votre application principale n'aurait pas besoin d'être modifiée en aucune façon.la source
extern "C"
car ladlsym
fonction est une fonction C. Et pour charger dynamiquement lacreate_object
fonction, elle utilisera une liaison de style C. Si vous n'utilisez pas leextern "C"
, il n'y aurait aucun moyen de connaître le nom de lacreate_object
fonction dans le fichier .so, à cause de la modification des noms dans le compilateur C ++.Ce qui suit montre un exemple de bibliothèque de classes partagée shared. [H, cpp] et un module main.cpp utilisant la bibliothèque. C'est un exemple très simple et le makefile pourrait être amélioré. Mais cela fonctionne et peut vous aider:
shared.h définit la classe:
shared.cpp définit les fonctions getx / setx:
main.cpp utilise la classe,
et le makefile qui génère libshared.so et relie main à la bibliothèque partagée:
Pour exécuter «main» et créer un lien avec libshared.so, vous devrez probablement spécifier le chemin de chargement (ou le mettre dans / usr / local / lib ou similaire).
Ce qui suit spécifie le répertoire actuel comme chemin de recherche des bibliothèques et exécute main (syntaxe bash):
Pour voir que le programme est lié à libshared.so, vous pouvez essayer ldd:
Imprime sur ma machine:
la source
-L. -lshared -Wl,-rpath=$$(ORIGIN)
lors de la liaison et déposez-leLD_LIBRARY_PATH=.
.Fondamentalement, vous devez inclure le fichier d'en-tête de la classe dans le code où vous souhaitez utiliser la classe dans la bibliothèque partagée. Ensuite, lorsque vous créez un lien, utilisez l'indicateur «-l» pour lier votre code à la bibliothèque partagée. Bien sûr, cela nécessite que le .so soit là où le système d'exploitation peut le trouver. Voir 3.5. Installation et utilisation d'une bibliothèque partagée
L'utilisation de dlsym est utilisée lorsque vous ne savez pas au moment de la compilation quelle bibliothèque vous souhaitez utiliser. Cela ne semble pas être le cas ici. Peut-être que la confusion est que Windows appelle les bibliothèques chargées dynamiquement que vous fassiez la liaison à la compilation ou à l'exécution (avec des méthodes analogues)? Si tel est le cas, vous pouvez considérer dlsym comme l'équivalent de LoadLibrary.
Si vous avez vraiment besoin de charger dynamiquement les bibliothèques (c'est-à-dire, ce sont des plug-ins), alors cette FAQ devrait vous aider.
la source
En plus des réponses précédentes, j'aimerais attirer l'attention sur le fait que vous devriez utiliser l' idiome RAII (Resource Acquisition Is Initialisation) pour être sûr de la destruction des gestionnaires.
Voici un exemple de travail complet:
Déclaration d'interface
Interface.hpp
::Contenu de la bibliothèque partagée:
Gestionnaire de bibliothèque partagée dynamique
Derived_factory.hpp
::Code client:
Remarque:
.hpp
et.cpp
fichiers.new
/delete
.Deux articles clairs pour obtenir plus de détails:
la source