c++ - 与 dlopen 的动态链接 : symbol not found

标签 c++ linux dlopen dynamic-links

我想加载我自己的C++动态链接库,这是我的测试代码:

添加.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++ 项目:

主要.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++ 中的 name mangling 引起的,但我不知道如何解决,我想在动态链接中使用 std::vector,所以我需要使用 C++而不是 c 来构建 .so 文件。

最佳答案

大多数 C++ 实现使用 name mangling (在错位名称中编码一些类型信息)。

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

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

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")

参见 nm(1) , dlopen(3) , dlsym(3) , C++ dlopen minihowto , Drepper 的 How To Write Shared Libraries , c++filt了解更多。

出于可读性原因,您可以使用 typedef 来定义签名(插件中的 dlsym 可用函数),例如 here .

关于c++ - 与 dlopen 的动态链接 : symbol not found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49187610/

相关文章:

c++ - 在堆中共享一个对象

c++ - 柔性 : use of yymore()

linux - NXP i.MX6 上的嵌入式 Electron

linux - 使用标准输出/标准输入将 tar 转换为 zip

c++ - 在 C++ 中使用 dlopen 的 undefined reference 错误

C++ bool std::operator < 带有键 std::unordered_set<int,std::hash<int>> 的映射错误

c++ - 非托管 C++ 程序集的加载顺序(特别是 VS C++ 2015 可再发行组件和通用 CRT)

linux - 在 Linux 上运行 DialogFlow 查询

Linux 共享库依赖于 dlopen 使用 RTLD_LOCAL 打开的另一个共享库中的符号

c - 当提供库地址时,如何获取共享库中符号的地址?