Использование классов C++ в библиотеках .so
-
09-06-2019 - |
Вопрос
Я пытаюсь написать небольшую библиотеку классов для курса C++.
Мне было интересно, можно ли определить набор классов в моем общем объекте, а затем использовать их непосредственно в моей основной программе, демонстрирующей библиотеку.Есть ли какие-то хитрости?Я помню, как давно читал (до того, как начал заниматься программированием), что классы C++ работали только с MFC .dll, а не с простыми, но это только сторона Windows.
Решение
Классы C++ отлично работают в общих библиотеках .so (они также работают в библиотеках DLL, отличных от MFC, в Windows, но это не совсем ваш вопрос).На самом деле это проще, чем в Windows, поскольку вам не нужно явно экспортировать символы из библиотек.
Этот документ ответит на большинство ваших вопросов: http://people.redhat.com/drepper/dsohowto.pdf
Главное, что следует помнить, — это использовать -fPIC
параметр при компиляции, и -shared
вариант при связывании.В сети можно найти множество примеров.
Другие советы
Мое решение/тестирование
Вот мое решение, и оно делает то, что я ожидал.
Код
кот.хх :
#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;
}
Сборник
Сначала вы компилируете общую библиотеку:
$ g++ -Wall -g -fPIC -c cat.cpp
$ g++ -shared -Wl,-soname,libcat.so.1 -o libcat.so.1 cat.o
Затем скомпилируйте основной исполняемый файл или программу на C++, используя классы в библиотеках:
$ 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
$
Насколько я понимаю, это нормально, если вы связываете файлы .so, которые были скомпилированы с использованием одного и того же компилятора.Разные компиляторы по-разному искажают символы и не могут связать их.
Это одно из преимуществ использования COM в Windows: оно определяет стандарт размещения ООП-объектов в DLL.Я могу скомпилировать DLL с помощью GNU g++ и связать ее с EXE-файлом, скомпилированным с помощью MSVC или даже VB!