GCC ダイナミック リンク ライブラリの仕様と問題点

Linuxのgccリンク規則:
ソースコードコンパイル時、リンク時の検索順序は、
(1) -Lで指定したパス、左から右へ検索
(2) 環境変数LIBRARY_PATHで指定したパス、「:」で区切る左から 右に移動して検索
(3) 指定したパス順序で /etc/ld.so.conf を
検索 (4) /lib および /usr/lib (64 ビットの場合は /lib64 および /usr/lib64)

ダイナミック ライブラリ呼び出しの検索シーケンス:
(1) コード内でハードコーディングされている ld の -rpath パラメータで指定されたパス
(2) ld スクリプトで指定されたパス
(3) LD_LIBRARY_PATH で指定されたパス
(4) /etc/ld. so.conf (5) で指定されたパス
/lib および /usr/lib (64 ビットでは /lib64 および /usr/lib64)

一般に、リンクする場合は -L を使用して検索パスを指定し、ダイナミック リンク ライブラリを呼び出す場合は LD_LIBRARY_PATH を使用してリンク パスを指定します。

注意すべきもう 1 つの問題は、最初のものが見つかった限り、それが返され、後続のものが再度検索されないことです。 

例: -L./A -L./B -lx A には libx.a があり、B には libx.a と libx.so があります。このとき、ダイナミック ライブラリの代わりに ./A の libx.a が使用されます。 ./A が最初に見つかり、同じ名前のダイナミック ライブラリが存在しないため、優先順位の原則に従います。


ダイナミック リンク ライブラリの場合、実際のシンボルの配置は実行時に実行されます。.so をコンパイルするときに、必要なライブラリが一緒にコンパイルされていない場合、たとえば、libx.so は uldict を使用する必要がありますが、libx のコンパイルを忘れます。 .so に追加すると、libx.so のコンパイル時にエラーは報告されません。これは、現時点では libx.so がライブラリとみなされ、特定の実装を認識せずに使用できるいくつかのシンボルをその中に含めることは合法であるためです。 in 実行時または別のバイナリ プログラムのコンパイル時に指定します。

g++ -Lpath -lx を使用してコンパイルすると、リンカーは uldict の必要なシンボル テーブルが見つからないことを検出し、エラーを報告します。ただし、プログラムが dlopen を使用してロードされる場合は、実行中であるため、プログラムは次のようになります。この場合、その場所は直接実行され、エラーが報告されます。また、動的ライブラリ内で外部インターフェースを宣言・定義したものの実装を忘れた場合も同様のエラーが発生します。

このようなエラーが実行時に報告された場合は、リンクされていないライブラリや実装されていないインターフェイスが原因であるかどうかに注意する必要があります。

上記の基礎を踏まえると、未定義参照エラーと未定義シンボル エラーの原因が次のとおりであることを理解するのは難しくありません。
(1) 対応するライブラリ (.o/.a/.so) が指定されていない。ライブラリ (-lXXX) を指定せずに、またはライブラリ パス (-LYYY) を指定せずに、ライブラリで定義されたエンティティを使用すると、このエラーが発生します。
(2) 接続ライブラリのパラメータの順序が間違っています。デフォルトでは、ライブラリを使用するための -l の要件は、静的か動的かに関係なく、ライブラリが基本的であればあるほど、最後にさらに基本的に記述する必要があることです。
(3) gcc/ld バージョンの不一致。Gcc/ld バージョンの互換性の問題。gcc2 と gcc3 のメジャー バージョン間の互換性の問題 (実際、gcc3.2 ~ 3.4 にもある程度そのような問題があります) により、上位バージョンのマシンで下位バージョンのマシンを使用すると、このようなエラーが発生する問題は、32 ビット環境でより一般的であり、また、64 ビット ライブラリを誤って 32 ビット環境で使用したり、逆に 32 ビット ライブラリを 64 ビット環境で使用したりすることもあります。
(4) C/C++ の相互依存性と連携。gcc と g++ のコンパイル結果を混合して使用する場合は、インターフェイスの両側で extern "C" を使用できるようにする必要があります。64 ビット環境では、gcc を -lstdc++ で g++ ライブラリにリンクする必要があります。詳細については、混合コンパイルに関する前述の説明を参照してください。
(5) 実行時にエラーが報告されました。この問題は基本的に、dlopen メソッドを使用して .so をロードするプログラムが原因ですが、.so は必要なすべてのライブラリをリンクしていません。詳細については、静的ライブラリと動的ライブラリの混合使用に関する上記の説明を参照してください。

おすすめ

転載: blog.csdn.net/HideInTime/article/details/129027130