Bry*_*ord 2 c c++ linker dlopen
我试图允许共享库从正在加载的进程中调用一个函数.该库是用C语言编写的,C语言是C++中的"内核".
kernel.cpp:
#include <stdio.h>
#include <dlfcn.h>
typedef void(*func_t)();
extern "C" {
void test();
}
int main() {
char *error;
void *handle = dlopen("./library.so", RTLD_LAZY);
if((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
return 1;
}
func_t init = (func_t)dlsym(handle, "init");
if((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
return 1;
}
init();
return 0;
}
void test() {
fprintf(stderr, "test() called.\n");
}
Run Code Online (Sandbox Code Playgroud)
LIBRARY.C:
#include <stdio.h>
void test();
void init() {
fprintf(stderr, "init() called.\n");
test();
}
Run Code Online (Sandbox Code Playgroud)
生成文件:
all:
g++ -ldl kernel.cpp -o kernel
gcc -fpic -shared library.c -o library.so
./kernel
Run Code Online (Sandbox Code Playgroud)
objdump -x内核
SYMBOL TABLE:
...
000000000040088b g F .text 0000000000000024 test
Run Code Online (Sandbox Code Playgroud)
运行程序,我得到以下输出:
init() called.
./kernel: symbol lookup error: ./library.so: undefined symbol: test
Run Code Online (Sandbox Code Playgroud)
如果我将dlopen更改为使用RTLD_NOW,我会得到:
./library.so: undefined symbol: test
Run Code Online (Sandbox Code Playgroud)
为什么图书馆很难找到那个符号,当它明显没有被破坏,坐在那里?
默认情况下不会导出可执行文件的符号.
您需要-export-dynamic链接标志来链接可执行文件:
g++ -ldl -Wl,-export-dynamic kernel.C -o kernel
Run Code Online (Sandbox Code Playgroud)
引用ld手册页,其中描述了您的确切场景:
If you use "dlopen" to load a dynamic object which needs to refer
back to the symbols defined by the program, rather than some other
dynamic object, then you will probably need to use this option when
linking the program itself.
Run Code Online (Sandbox Code Playgroud)