1

g++ を使用して、Linux で C++ アプリを作成しています。私のアプリは、必要な単純な API を公開する共有ライブラリにリンクしています。このライブラリは、多数の追加の共有ライブラリを内部的に参照します。それらをすべて見つけて Makefile に追加し、それらをリンクする必要がありました。

私のアプリは、プライマリ ライブラリが依存するいずれかのライブラリにリンクする必要があると思います。このリンク要件を回避する唯一の方法は、すべての依存関係の静的ライブラリでプライマリ ライブラリをコンパイルすることですか? これは、dlopen/dlsym 経由でプラグイン モデルを使用する場合にも当てはまりますか?

タイ

4

3 に答える 3

4

このリンク要件を回避する唯一の方法は、すべての依存関係の静的ライブラリでプライマリ ライブラリをコンパイルすることですか?

いいえ。共有ライブラリ自体が、依存する共有ライブラリにリンクできます。ほとんどのリンカーはこれらのライブラリも選択し、リンカーの段階で言及しなくても、実行可能ファイルをそれらのライブラリにリンクします。

あなたの場合、共有ライブラリが必要なライブラリにリンクしていないようです。lddツールは、この点で役立ちます。

例として、次の共有ライブラリを作成するとします。

gcc -shared foo.o -o libfoo.so -lm

これでlibfoo.so、数学ライブラリ (libm) にリンクされます。libfoo.so にリンクされたアプリケーションは、libm にもリンクされます。

gcc -o prog main.o -lfoo

一方、共有ライブラリが lib にリンクされておらず、

 gcc -shared foo.o  -o libfoo.so

アプリケーションをリンクするときは、libm に明示的にリンクする必要があります。

gcc -o prog main.o -lfoo -lm

共有ライブラリを dlopen() すると、実行時リンカーは、共有ライブラリがリンクされているすべてのライブラリを読み込みます (まだ読み込まれていない場合を除く)。したがって、dlopen() するライブラリが依存するライブラリに対してリンクされておらず、実行可能ファイルもそれらのライブラリに対してリンクされていない場合、dlopen() は失敗します (RTLD_LAZY を指定しない限り、後で失敗します)。

于 2012-07-09T19:16:27.583 に答える
1

私のアプリは、プライマリ ライブラリが依存するいずれかのライブラリにリンクする必要があると思います。

アプリがこれらのシンボルを (API 共有ライブラリを介して間接的にではなく) 直接使用している、共有ライブラリが適切にリンクされていないため、依存するライブラリにリンクされていないように思えます。その共有ライブラリが作成されたときにその依存関係がリンクされてい-lた場合、アプリを API ライブラリにリンクするときに自動的にリンクされます。

このリンク要件を回避する唯一の方法は、すべての依存関係の静的ライブラリでプライマリ ライブラリをコンパイルすることですか?

それは一つの方法ですが、唯一の方法ではありません。

これは、dlopen/dlsym 経由でプラグイン モデルを使用する場合にも当てはまりますか?

プラグインが依存するライブラリに正しくリンクされている限り...いいえ、その場合、リンカはdlopen実行時にどのライブラリを使用するかをおそらく知ることができないため、それらの依存関係がどうなるかを知ることができないため、リンク時に名前を付ける必要はありません。ロードされる可能性のあるすべてのプラグインを事前に知らなければ、それは不可能です。

プラグイン ライブラリが適切にリンクされていない場合、それらを試したときに同じ問題が発生しdlopenます。

于 2012-07-09T19:20:41.890 に答える
-1

私のアプリは、プライマリ ライブラリが依存するいずれかのライブラリにリンクする必要があると思います。このリンク要件を回避する唯一の方法は、すべての依存関係の静的ライブラリでプライマリ ライブラリをコンパイルすることですか?

もちろん。回避策はありません。静的リンクを使用するか、ライブラリ (ABI と互換性がない場合は正しいバージョン) をライブラリのランタイム検索パスに含めるかのいずれかです。

これは、dlopen/dlsym 経由でプラグイン モデルを使用する場合にも当てはまりますか?

いいえ。そのためには、ロード元のパスに共有ライブラリが必要です。

于 2012-07-09T19:09:48.477 に答える