与dlopen的动态链接:未找到符号

时间:2018-03-09 06:10:33

标签: c++ linux dlopen dynamic-links

我想为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 ++中的名称错误造成的,但我不知道如何解决它,我想在动态链接中使用std::vector,所以我需要使用C ++而不是c来构建。所以档案。

1 个答案:

答案 0 :(得分:3)

大多数C ++实现都使用name mangling(用于对错位名称中的某些类型信息进行编码)。

您需要声明extern "C"dlsym相关的任何符号(即与之一起使用)(这会禁用该符号上的名称修改)。

所以你的add.cpp文件在其#include - s指令之后应该有以下声明:

extern "C" int add(int c);

BTW,请使用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")

有关详情,请参阅nm(1)dlopen(3)dlsym(3)C++ dlopen minihowto,Drepper的How To Write Shared Librariesc++filt

出于可读性原因,您可以使用typedef来定义(dlsym - 插件中的{{1}}个功能)的签名,例如here