web-dev-qa-db-ja.com

ロード時の動的リンクと実行時の動的リンクの違い

プログラムをメモリにロードする場合、ロード時の動的リンクと実行時の動的リンクの違いは何ですか?

25
jennyson

ロード時のリンクとは、実行可能ファイル(または別のライブラリ)によって参照されるライブラリ内のシンボルが、オペレーティングシステムによって実行可能ファイル/ライブラリがメモリにロードされるときに処理されることです。

ランタイムリンクとは、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ファイル)のロードを試みます。すでにライブラリがメモリにある可能性があります。

20
Aiden Bell

Aiden Bellが基本をカバーしましたが、私は追加します:

ロード時の動的リンクは通常、プログラムの起動時に.libまたは.aファイルにあるシンボルへのランタイムリンクを自動的に確立するためのコードを含む.dllまたは.soファイルにアプリケーションを静的にリンクすることによって実現されます。これは通常、固定機能(Cランタイムライブラリなど)用であり、実行可能ファイルのサイズを小さく保ちながら(共通のコードを単一のライブラリに分解することにより)、プログラムがライブラリのバグ修正のメリットを享受できるようにします。

ランタイムリンクは、プラグインの読み込みなど、より動的な機能に使用されます。 Aidenが言ったように、LoadLibrary()または同等のものを使用して、実行時にモジュールをプログラムにアクティブにアタッチします。おそらく、プラグインDLLを含むディレクトリに問い合わせ、それぞれを順番にロードして、自家製のプラグインAPIと通信します。そうすることで、プログラムは、アプリがコンパイル/リンクされたときにも存在しなかったモジュールをロードできるため、デプロイ後に有機的に成長できます。

基本的に、どちらのメソッドもLoadLibrary() AP​​Iを呼び出すことになりますが、前者の場合は固定のシンボルとライブラリのセットを使用し、後者の場合はより動的なセットを使用します。

15
Drew Hall

質問されてから久しぶりです。そして、エイデンとドリューの答えは本質のほとんどをカバーしていました。プログラマーの観点からいくつか追加したいと思います。

ロードタイムダイナミックリンクを使用する場合は、LIBファイルにリンクする必要があります。そして、コードでは、通常どおり明示的にメソッドを呼び出すことができます。 (コードサンプルについては、 ロード時ダイナミックリンクの使用 を参照してください)

ランタイムダイナミックリンクを使用する場合は、DLL読み込み/解放、および関数ルックアップを自分で管理する必要があります( ランタイムダイナミックリンクの使用 を参照)。コードサンプル)

2つのオプションのどちらかを選択するには、 使用するリンク方法の決定 を確認してください。

したがって、ロード時ダイナミックリンクはプログラマーの労力を節約するためのもう1つの方法だと思います。しかし、それはある程度の拡張性を犠牲にしてもたらされます。インポートライブラリとして使用するLIBファイルに対応するDLLのみを使用できます。

基本的に、両方のリンクアプローチはWindowsプラットフォームでLoadLibrary()APIを使用します。

14
smwikipedia

ロード時のダイナミックリンク実行可能ファイルはDLLライブラリにリンクされていますが、ランタイムダイナミックリンクでは実行可能ファイルはどのDLLにもリンクされていません。

アプリケーションの起動パフォーマンスが重要な場合は、ランタイムダイナミックリンクが望ましい

1
imsaiful