dlopen找不到符合标准的符号

时间:2014-08-27 11:54:04

标签: c++ c linker dlopen

我正在尝试允许共享库从正在加载的进程中调用函数。该库是用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");
}

LIBRARY.C:

#include <stdio.h>

void test();

void init() {
        fprintf(stderr, "init() called.\n");
        test();
}

生成文件:

all:
        g++ -ldl kernel.cpp -o kernel
        gcc -fpic -shared library.c -o library.so
        ./kernel

objdump -x kernel

SYMBOL TABLE: 
... 
000000000040088b g     F .text  0000000000000024    test

运行程序,我得到以下输出:

init() called.
./kernel: symbol lookup error: ./library.so: undefined symbol: test

如果我更改dlopen以使用RTLD_NOW,我会得到:

./library.so: undefined symbol: test

为什么图书馆很难找到那个符号,当它明显没有被破坏时,坐在那里?

1 个答案:

答案 0 :(得分:5)

默认情况下不会导出可执行文件的符号。

您需要-export-dynamic链接标志来链接可执行文件:

g++ -ldl -Wl,-export-dynamic kernel.C -o kernel

引用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.