プログラムをメモリにロードするとき、ロード時の動的リンクと実行時の動的リンクの違いは何ですか?
5 に答える
ロード時のリンクは、実行可能ファイル(または別のライブラリ)によって参照されるライブラリ内のシンボルが、オペレーティングシステムによって実行可能ファイル/ライブラリがメモリにロードされるときに処理される場合です。
ランタイムリンクとは、OSまたはライブラリを介して提供されるAPIを使用して、必要なときにDLLまたはDSOをロードし、シンボル解決を実行する場合です。
私はWindowsDLLよりもLinuxDSOについてよく知っていますが、原則は同じである必要があります。.NETライブラリは異なる場合があります。
Linuxでは、プラグインアーキテクチャはこのように行われます。プログラムはランタイムリンクを使用してライブラリをロードし、いくつかの関数を呼び出します。それから多分それをアンロードします。また、同じシンボルがエクスポートされた複数のライブラリを衝突することなくロードできます。DLLはほとんど同じように機能すると思います。
実行可能ファイルのシンボルテーブルには、ライブラリによる入力が必要な「空白」があります。これらの空白スペースは通常、ロード時またはコンパイル時に埋められます。ランタイムリンクを使用すると、シンボルテーブルの「空白」の必要性をなくすことができます。
ランタイムリンクが役立つもう1つのシナリオは、ライブラリをデバッグする場合、または実行時に複数のABI/API互換ライブラリから選択する場合です。私はよく「foo」と「foo_unstable」というライブラリを持っていて、2つを切り替えていくつかのテストを行うテストアプリを持っています。
Linuxでは、ロード時に実行可能ファイルがどのライブラリにリンクしているかを確認するには、ldd
コマンドを実行して(/ bin / ls上で)などの出力を取得します。
linux-vdso.so.1 => (0x00007fff139ff000)
librt.so.1 => /lib64/librt.so.1 (0x0000003c4f200000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003c4fa00000)
libcap.so.2 => /lib64/libcap.so.2 (0x0000003c53a00000)
libacl.so.1 => /lib64/libacl.so.1 (0x0000003c58e0000
オペレーティングシステムは、ロード時にライブラリ(.soファイル)のロードを試みます。すでにライブラリがメモリにある可能性があります。
Aiden Bell が基礎を説明しましたが、以下を追加します。
通常、読み込み時の動的リンクは、プログラムの起動時にまたはファイルで検出されるシンボルへのランタイム リンクを自動的に確立するためのコードを含む.lib
またはファイルにアプリケーションを静的にリンクすることによって実現されます。これは通常、固定機能 (つまり、C ランタイム ライブラリなど) 用であり、実行可能ファイルのサイズを小さく保ちながら (一般的なコードを 1 つのライブラリに分割することによって)、プログラムがライブラリのバグ修正の利点を享受できるようにします。.a
.dll
.so
ランタイム リンクは、プラグインの読み込みなどのより動的な機能に使用されます。Aiden が言っLoadLibrary()
たように、おそらくプラグイン DLL を含むディレクトリに問い合わせ、それぞれを順番にロードし、自家製のプラグイン API と対話することによって、実行時にモジュールをアクティブにプログラムにアタッチするために、または同等のものを使用します。そうすることで、プログラムは、アプリがコンパイル/リンクされたときに存在しなかったモジュールをロードできるため、展開後に有機的に成長できます。
基本的に、どちらのメソッドも最終的に API を呼び出しLoadLibrary()
ますが、前者の場合はシンボルとライブラリの固定セットを使用し、後者の場合はより動的なセットを使用します。