我想加载我自己的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
型
然后我尝试用dlopen
动态地将它链接到我的C++项目:
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
。
有一个类似的question,但答案不能解决我的问题。我知道这个问题可能是由C中的名称mangling引起的,但我不知道如何解决它,我想在动态链接中使用std::vector
,所以我需要使用C而不是C来构建.so文件。
1条答案
按热度按时间yws3nbqq1#
大多数C++实现都使用name mangling(将一些类型信息编码到变形名称中)。
您需要声明
extern "C"
任何与dlsym
相关的符号(即与dlsym
一起使用)(这将禁止对该符号进行名称修改)。因此,
add.cpp
文件在其#include
-s指令之后应该有以下声明:字符串
顺便说一句,用
nm -D -C add.so
检查你的插件的动态符号表。当然,
extern "C"
函数可以使用C++的特性和类型。型
在主程序中执行一些
dlsym(handle, "sum_vector_elements")
。请参阅nm(1),dlopen(3),dlsym(3),C++ dlopen minihowto,Drepper's How To Write Shared Libraries,c++filt了解更多信息。
出于可读性的考虑,您可以使用
typedef
来定义(插件中支持dlsym
的函数的)签名,如here。