c - `-rdynamic` 到底做了什么,什么时候需要它?

标签 c gcc shared-libraries elf dynamic-loading

-rdynamic(或链接器级别的--export-dynamic)究竟做了什么,它与 定义的符号可见性有何关系-fvisibility* 标志或可见性 pragma__attribute__s?

对于 --export-dynamicld(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();
}

ma​​in.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.somain.c 成为 dlopens 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/

相关文章:

c - 即使我添加 %s,格式也不是字符串文字

linux - "LD_LIBRARY_PATH"设置的目录是否会找到其子目录?

c - 在同一进程中多次加载共享库的地址空间

cmake - 如何在 CMakeLists 中包含外部库?

c - C项目中的段错误

c - 在结构体数组后打印字符

c - 执行 ("/bin/sh", 0, 0);在管道中

在Win7上将rabbitmq-c编译为x64

linux - ELF 动态加载程序符号查找顺序

c - unix gcc 文件覆盖