Я хочу загрузить свою собственную библиотеку динамических ссылок для C ++, вот мой тестовый код:
add.cpp
#include <vector>
using namespace std;
int add(int c)
{
vector<int> v;
int i;
int sum = 0;
for (i = 0; i < c; i++)
{
sum = sum + i;
}
return sum;
}
Я выполняю команду, как показано ниже, чтобы построить add.so
:
g++ -fPIC -shared add.cpp -o add.so
Затем я пытаюсь динамически связать его с моим C ++ проектом dlopen
:
main.cpp
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
typedef int (*add_func_ptr)(int);
int main(int argc, char **argv)
{
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen("./add.so", RTLD_LAZY);
if (!handle)
{
fputs(dlerror(), stderr);
exit(1);
}
add_func_ptr addfun;
addfun = (add_func_ptr)dlsym(handle, "add");
if ((error = dlerror()) != NULL)
{
fputs(error, stderr);
exit(1);
}
printf("%d\n", (*addfun)(2));
dlclose(handle);
}
Наконец, я компилирую это:
g++ main.cpp -ldl -o main
Тем не менее, когда я выполняю ./main
Я всегда получаю ошибку: symbol not found
,
Есть похожий вопрос, но ответ не смог решить мою проблему. Я знаю, что проблема может быть вызвана искажением имени в C ++, но я не знаю, как ее решить, я хочу использовать std::vector
в динамической ссылке, поэтому мне нужно использовать C ++ вместо c для создания .so файла.
Большинство реализаций C ++ используют название искажения (для кодирования некоторой информации о типе в искаженном имени).
Вы должны объявить extern "C"
любой символ, связанный с (т.е. используется с) dlsym
(это отключает искажение имени для этого символа).
Так что ваши add.cpp
файл должен иметь следующую декларацию после его #include
Директивы:
extern "C" int add(int c);
Кстати, проверить с nm -D -C add.so
динамическая таблица символов вашего плагина.
Конечно, extern "C"
Функция может использовать функции и типы C ++. Чтобы вы могли код
extern "C" int sum_vector_elements(const std::vector<int> &v);
int sum_vector_elements(const std::vector<int> &v) {
int s =0;
for (int x: v) { s += x; };
return s;
}
и сделать некоторые dlsym(handle, "sum_vector_elements")
в вашей основной программе.
Увидеть нм (1), dlopen (3), dlsym (3), C ++ dlopen minihowto, Drepper-х Как писать общие библиотеки, C ++ ФИЛТР для большего.
Для удобства чтения вы можете использовать typedef
определить подписи (из dlsym
-функции в плагинах) Вот.
Других решений пока нет …