-rdynamic
(或链接器级别的--export-dynamic
)究竟做了什么,它与 定义的符号可见性有何关系-fvisibility*
标志或可见性 pragma
和 __attribute__
s?
对于 --export-dynamic
,ld(1)提及:
... 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. ...
我不确定我是否完全理解这一点。您能否提供一个示例,如果没有 -rdynamic
就不能工作,但是有它就可以吗?
编辑:
我实际上尝试编译了几个虚拟库(单个文件、多个文件、各种 -O 级别、一些函数间调用、一些隐藏的符号、一些可见的),有和没有 -rdynamic
,和到目前为止,我得到的是字节相同输出(当然是在保持所有其他标志不变的情况下),这非常令人费解。
最佳答案
这里有一个简单的示例项目来说明-rdynamic
的使用。
bar.c
extern void foo(void);
void bar(void)
{
foo();
}
main.c
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
void foo(void)
{
puts("Hello world");
}
int main(void)
{
void * dlh = dlopen("./libbar.so", RTLD_NOW);
if (!dlh) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
void (*bar)(void) = dlsym(dlh,"bar");
if (!bar) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
bar();
return 0;
}
生成文件
.PHONY: all clean test
LDEXTRAFLAGS ?=
all: prog
bar.o: bar.c
gcc -c -Wall -fpic -o $@ $<
libbar.so: bar.o
gcc -shared -o $@ $<
main.o: main.c
gcc -c -Wall -o $@ $<
prog: main.o | libbar.so
gcc $(LDEXTRAFLAGS) -o $@ $< -L. -lbar -ldl
clean:
rm -f *.o *.so prog
test: prog
./$<
这里,bar.c
成为共享库 libbar.so
而 main.c
成为
dlopen
s libbar
并从该库调用 bar()
的程序。
bar()
调用foo()
,它在bar.c
外部,在main.c
中定义。
所以,没有-rdynamic
:
$ make test
gcc -c -Wall -o main.o main.c
gcc -c -Wall -fpic -o bar.o bar.c
gcc -shared -o libbar.so bar.o
gcc -o prog main.o -L. -lbar -ldl
./prog
./libbar.so: undefined symbol: foo
Makefile:23: recipe for target 'test' failed
和-rdynamic
:
$ make clean
rm -f *.o *.so prog
$ make test LDEXTRAFLAGS=-rdynamic
gcc -c -Wall -o main.o main.c
gcc -c -Wall -fpic -o bar.o bar.c
gcc -shared -o libbar.so bar.o
gcc -rdynamic -o prog main.o -L. -lbar -ldl
./prog
Hello world
关于c - `-rdynamic` 到底做了什么,什么时候需要它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36692315/