1. ホーム
  2. c

[解決済み] rdynamic` は具体的に何をするもので、どのような場合に必要なのでしょうか?

2022-02-02 20:38:22

質問

は具体的にどのようなものですか? -rdynamic (または --export-dynamic で定義されるシンボルの可視性とどのような関係があるのでしょうか? -fvisibility* フラグまたは可視性 pragma__attribute__ s?

について --export-dynamic , ld(1) が言及されています。

... を参照する必要がある動的オブジェクトをロードするために "dlopen" を使用した場合、その動的オブジェクトは、その動的オブジェクトを参照する必要があります。 プログラムによって定義されたシンボルではなく、他のダイナミックな オブジェクトを使用する場合、おそらく このオプションは、プログラム自体をリンクするときに使用します。...

完全に理解できているわけではないのですが。を使用しないと動作しない例を提示していただけませんか? -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.somain.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