3

簡単な例を見てみましょう。

void foo() {}

int main()
{
       return 0;
}

それを作成し、動的シンボルテーブルを確認します。

$ g++ test.cpp -o test
$ nm --dynamic test
0804849c R _IO_stdin_used
         w __gmon_start__
         U __libc_start_main

さすがに見えませんfoo。そこで、未使用のシンボルを含めるようにビルドします。

$ gcc test.c -rdynamic -o test
$ nm --dynamic test
0804863c R _IO_stdin_used
         w _Jv_RegisterClasses
0804a010 A __bss_start
0804a008 D __data_start
         w __gmon_start__
080485e0 T __libc_csu_fini
08048570 T __libc_csu_init
         U __libc_start_main
0804a010 A _edata
0804a018 A _end
0804861c T _fini
08048638 R _fp_hw
08048438 T _init
080484a0 T _start
0804a008 W data_start
08048554 T foo
08048559 T main

fooそして、それがシンボルテーブルにあることがわかります。次に、静的バージョンを作成します。

$ gcc test.c -rdynamic -static -o test
$ nm --dynamic test
nm: test: No symbols

明示的に指定したのに、シンボルがなくなってしまいました。

GCCのマニュアルページによると:

-static動的リンクをサポートするシステムでは、これにより共有ライブラリとのリンクが防止されます。

私の関数foo()は共有ライブラリではありません。

このアプリケーションを展開し、それがを呼び出し、dlopen()ロードしたライブラリがを呼び出す必要があるfoo()場合、シンボルテーブルには参照が含まれなくなりfoo()、アプリケーションは失敗します。

これは最近私に起こりました。

-staticが-rdynamicを無効にするのはなぜですか?また、どうすれば回避できますか?

4

1 に答える 1

1

C ライブラリに静的にリンクされた実行可能ファイルのアイデアはあると思いますが、共有ライブラリへのエクスポートを提供することは、おそらく壊れた概念です。この場合はどうなりますか?共有ライブラリが (C ライブラリの独自のコピーを使用して) メモリを割り当て、それを (C ライブラリの別のコピーで) 解放する実行可能ファイルのルーチンに渡すとします。これは問題臭がします。一部のライブラリを静的にリンクする必要がある場合は、-Wl,-Bstaticそれらのライブラリの前にオプションを使用して、静的バージョンに対してリンクを強制することができます。

また、何が起こっているかをより詳細に制御する必要がある場合は、コンパイルとリンクのステップを別々にしてld、リンクのステップに直接使用する方がよい場合があります。使用しているコマンド ライン オプションに必ずしも役立つとは限りませんが、上記の問題を除いて「機能する」何かに到達できるのではないかと思います。

于 2012-09-12T08:36:02.223 に答える