使用dlopen加载的共享库如何引用全局符号

3
我可以帮您翻译。以下是翻译结果:

我有一个共享库,想从主程序中访问符号。例如:

main.c

#include <stdio.h>

void bar(void) { puts("bar"); }

extern void foo(void);

int main(void) {
    foo();
    return 0;
}

foo.c

#include <stdio.h>

extern void bar(void);

void foo(void) {
    puts("foo");
    bar();
}

我编译和运行的方式如下:

gcc -c -fpic foo.c
gcc -shared -o libfoo.so foo.o
gcc -L$(pwd) -o test main.c -lfoo
./test

我得到了我期望的输出:

foo
bar

然而,我必须使用dlopen()dlsym(),因为我想要控制库何时被加载。更改的文件如下:

main.c

#include <stdio.h>
#include <dlfcn.h>

void bar(void) { puts("bar"); }

int main(void) {
    void *handle = dlopen("./libfoo.so", RTLD_LAZY);
    void (*foo)(void) = (void(*)(void))dlsym(handle,"foo");
    foo();
    return 0;
}

foo.c

#include <stdio.h>
#include <dlfcn.h>

extern void bar(void);

void foo(void) {
    puts("foo");
    bar();
}

我改用以下方式进行编译和运行:
gcc -c -fpic foo.c
gcc -shared -o libfoo.so foo.o
gcc -o test main.c -ldl
./test

然而,这一次我得到了输出。
foo
./test: symbol lookup error: ./libfoo.so: undefined symbol: bar

如何从libfoo中引用主程序中的符号?
1个回答

5

在链接test时,需要添加-rdynamic选项:

gcc -o test main.c -ldl -rdynamic

来自这里

-rdynamic 在支持的目标上向ELF链接器传递标志-export-dynamic。这会指示链接器将所有符号添加到动态符号表中,而不仅仅是使用的符号。一些使用dlopen或允许从程序内获取回溯的用途需要此选项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接