Utiliser des classes C++ dans les bibliothèques .so
-
09-06-2019 - |
Question
J'essaie d'écrire une petite bibliothèque de classes pour un cours C++.
Je me demandais s'il était possible de définir un ensemble de classes dans mon objet partagé puis de les utiliser directement dans mon programme principal qui fait une démonstration de la bibliothèque.Y a-t-il des astuces impliquées ?Je me souviens avoir lu il y a longtemps (avant de vraiment commencer à programmer) que les classes C++ ne fonctionnaient qu'avec les .dll MFC et non avec les simples, mais ce n'est que le côté Windows.
La solution
Les classes C++ fonctionnent correctement dans les bibliothèques partagées .so (elles fonctionnent également dans les DLL non MFC sous Windows, mais ce n'est pas vraiment votre question).C'est en fait plus simple que Windows, car vous n'avez pas besoin d'exporter explicitement les symboles des bibliothèques.
Ce document répondra à la plupart de vos questions : http://people.redhat.com/drepper/dsohowto.pdf
Les principales choses à retenir sont d'utiliser le -fPIC
option lors de la compilation, et l'option -shared
option lors de la liaison.Vous pouvez trouver de nombreux exemples sur le net.
Autres conseils
Ma solution/test
Voici ma solution et elle fait ce que j'attendais.
Code
chat.hh :
#include <string>
class Cat
{
std::string _name;
public:
Cat(const std::string & name);
void speak();
};
cat.cpp :
#include <iostream>
#include <string>
#include "cat.hh"
using namespace std;
Cat::Cat(const string & name):_name(name){}
void Cat::speak()
{
cout << "Meow! I'm " << _name << endl;
}
main.cpp :
#include <iostream>
#include <string>
#include "cat.hh"
using std::cout;using std::endl;using std::string;
int main()
{
string name = "Felix";
cout<< "Meet my cat, " << name << "!" <<endl;
Cat kitty(name);
kitty.speak();
return 0;
}
Compilation
Vous compilez d'abord la bibliothèque partagée :
$ g++ -Wall -g -fPIC -c cat.cpp
$ g++ -shared -Wl,-soname,libcat.so.1 -o libcat.so.1 cat.o
Compilez ensuite l'exécutable principal ou le programme C++ en utilisant les classes des bibliothèques :
$ g++ -Wall -g -c main.cpp
$ g++ -Wall -Wl,-rpath,. -o main main.o libcat.so.1 # -rpath linker option prevents the need to use LD_LIBRARY_PATH when testing
$ ./main
Meet my cat, Felix!
Meow! I'm Felix
$
Si je comprends bien, c'est bien tant que vous liez des fichiers .so qui ont tous été compilés à l'aide du même compilateur.Différents compilateurs modifient les symboles de différentes manières et ne parviendront pas à les lier.
C'est l'un des avantages de l'utilisation de COM sous Windows, il définit une norme pour placer les objets POO dans les DLL.Je peux compiler une DLL en utilisant GNU g++ et la lier à un EXE compilé avec MSVC - ou même VB !