Я пытаюсь загрузить файл .so в мое приложение Qt под Linux. Это работает с использованием dlopen () и dlsym () для основных функций. Но мне нужно получить несколько списков строк из библиотеки .so, поэтому я попытался использовать общий файл .h для обоих, но не могу получить доступ к объекту из основного приложения.
Это то, что я до сих пор:
extmodule.h
#include <list>
#include <string>
using namespace std;
class ExtModule
{
public:
ExtModule();
list<string> L2MACSource;
list<string> L2MACDest;
...
modulefile.cpp
#include "extmodule.h"extern "C" ExtModule getCont() {
ExtModule modul;
modul.L2MACSource.push_back("...")
return modul;
}
extern "C" void hello()
{
cout << "hello" << endl;
}
main.cpp
#include "extmodule.h"...
dlopen("...../modulefile.so", RTLD_LAZY);
...
typedef ExtModule(*loadedFunc)();
loadedFunc ext_get = (loadedFunc)dlsym(ext_mod, "getCont");
typedef void (*hello_t)();
hello_t hello = (hello_t)dlsym(ext_mod, "hello");
hello();
ExtModule modul = ext_get();
Функция hello () работает безупречно, но я не могу заставить работать ext_get () (/external.so: неопределенный символ: _ZN9ExtModuleC1Ev). Мне нужно получить несколько списков из библиотеки .so, но я не знаю, правильно ли это. Кроме того, как вы, наверное, догадались, я не очень опытный программист. Любое предложение будет высоко оценено.
Спасибо за любую помощь.
Вам, вероятно, нужно скомпилировать и связать вашу основную программу с -rdynamic
флаг (чтобы попросить компоновщик выдавать динамические символы, чтобы имена из основной программы были видны плагинам), например
g++ -Wall -rdynamic -g main.cpp -o mainprog
возможно, некоторые библиотеки и дополнительные флаги отсутствуют, например, для Qt
и ваш плагин с
g++ -Wall -shared -g -fPIC modulefile.cpp -o module.so
возможно, также отсутствуют дополнительные флаги, например, для Qt
На практике Qt знает о плагины а также qmake
также имеет поддержку плагинов.
При использовании dlopen
& dlsym
вы всегда следует проверить на наличие ошибок:
ext_mod = dlopen("...../modulefile.so", RTLD_LAZY);
if (!ext_mod) {
fprintf(stderr, "dlopen failure: %s\n", dlerror());
exit (EXIT_FAILURE); }
а также
hello_t hello = (hello_t)dlsym(ext_mod, "hello");
if (!hello) {
fprintf(stderr, "dlsym failure: %s\n", dlerror());
exit (EXIT_FAILURE); }
Читать dlopen (3), Библиотека программ HowTo, C ++ dlopen mini howto, Бумага Дреппера: Как написать общие библиотеки, Расширенное программирование в Linux книга.
Кстати, вы не показываете весь свой код C ++. Пожалуйста, убедитесь, что у вас есть необходимые конструкторы и деструкторы. Читайте о правило трех (для старого C ++ 03), который становится правилом пяти в C ++ 11.
Вы можете использовать приведенную ниже команду для создания вашего * .so файла.
g ++ -shared -fPIC -o {libname} .so -l {имя файла * .so, где находится определение ExtModule} -L {путь к модулю.}