将共享库与 dlopen 一起使用 - 共享对象找不到加载程序导出的符号
Posted
技术标签:
【中文标题】将共享库与 dlopen 一起使用 - 共享对象找不到加载程序导出的符号【英文标题】:Using shared libraries with dlopen - shared object cannot find symbol exported by the loading program 【发布时间】:2015-03-06 13:22:35 【问题描述】:所以,我正在尝试运行以下示例。
header.h
extern "C"
void registerfunc();
;
main.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
然后,我想使用我自己的registerfunc,它的写法如下:
main.h:
extern "C"
void test();
;
main.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 ?? ()
这让我有点困惑,至于如何让 test.so 调用由它的被调用者定义的东西。请问您能帮忙吗?
【问题讨论】:
【参考方案1】:您在这里至少有三个不同的问题:
较小的一个是您有两个名为main.cpp
的文件,尚不完全清楚哪个命令引用了您的问题中的哪个文件。
更大的问题是您希望 test.so
绑定到 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
),而不是一个可执行文件。像运行可执行文件一样运行这样的共享库会导致您观察到的崩溃。
【讨论】:
以上是关于将共享库与 dlopen 一起使用 - 共享对象找不到加载程序导出的符号的主要内容,如果未能解决你的问题,请参考以下文章