gpt4 book ai didi

c++ - 将共享库与 dlopen 一起使用 - 共享对象找不到加载程序导出的符号

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:53:26 28 4
gpt4 key购买 nike

因此,我尝试运行以下示例。

标题.h

extern "C" {
void registerfunc();
};

主要.cpp

#include "header.h"
#include <dlfcn.h>
#include <iostream>

using namespace std;

typedef void (*register_func)();

void registerfunc() {
cout << "register func has been called" << endl;
}

int main() {
void* lib_handle = dlopen("./test/test.so", RTLD_NOW | RTLD_GLOBAL);

if(lib_handle == NULL){
cout << "no such lib:" << dlerror() <<endl;
return 0;
}

register_func reg = (register_func)dlsym(lib_handle, "test");

if(reg == NULL){
cout << "Cannot load symbol" << dlerror() << endl;;
} else {
reg();
}
return 0;
}

它是用下面的makefile编译的

all:
g++ main.cpp -ldl

然后,我想用自己的so中的registerfunc,写法如下:

主要.h:

extern "C"
{
void test();
};

主要.cpp

#include "main.h"
#include "../header.h"

void test() {
registerfunc();
}

生成文件:

all:
g++ main.cpp -fPIC -shared -o test.so

当我以这种方式编译并运行 a.out(第一个 main 的输出)时,我得到:

 no such lib: ./test/test.so: undefined symbol: registerfunc

但是,如果我使用以下命令编译 a.out 和 test.so:

a.out -> g++ -g -fPIC -shared main.cpp -ldl
test.so -> g++ -g main.cpp -fPIC -shared -o test.so ../a.out

然后我遇到以下回溯的段错误(gdb -ex run a.out):

0x0000000000000001 in ?? ()

这让我有点困惑,关于如何 make test.so 调用由它的被调用者定义的东西。你能帮忙吗?

最佳答案

这里至少有三个独立的问题:

  • 较小的一个是您有两个名为 main.cpp 的文件,并且不完全清楚您的问题中哪个命令指的是哪个文件。

  • 更大的问题是您希望 test.so 绑定(bind)到 a.out 中的 registerfunc,但该函数未导出 来自 a.out 除非参与链接的共享库引用了该功能,或者您使用 -Wl 链接, --export-dynamic(导出所有 函数)。这才是真正的解决方案。

    您可以使用以下命令查看从您的 a.out 中导出了哪些函数:

    nm -D a.out | grep 'T'

  • 最后,当您执行此操作时:

    a.out -> g++ -g -fPIC -shared main.cpp -ldl

    您实际上是在创建共享库(名为 a.out),而不是可执行文件。像运行可执行文件一样运行这样的共享库会导致您所观察到的崩溃。

关于c++ - 将共享库与 dlopen 一起使用 - 共享对象找不到加载程序导出的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28899687/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com