私はWindowsでDLLをロードするのにLoadLibrary
関数を使用しています。私の質問はこれです:私は同じDLLのこのメソッドを複数回呼び出す場合、DLLの別のインスタンスにハンドルを取得するか、それらはすべて同じインスタンスを参照しますか?複数回DLLをロードしますか?
また、この動作はLinux SOファイルとどのように関連していますか、それは同じか全く異なっていますか、この点についてどのような前提ができますか?ありがとう。
私はWindowsでDLLをロードするのにLoadLibrary
関数を使用しています。私の質問はこれです:私は同じDLLのこのメソッドを複数回呼び出す場合、DLLの別のインスタンスにハンドルを取得するか、それらはすべて同じインスタンスを参照しますか?複数回DLLをロードしますか?
また、この動作はLinux SOファイルとどのように関連していますか、それは同じか全く異なっていますか、この点についてどのような前提ができますか?ありがとう。
MSDNドキュメントの状態:
システムがロードされたすべての モジュールのプロセスごとの参照カウントを保持します。 LoadLibraryを呼び出すと、参照カウントがインクリメントされます。 を呼び出すと、FreeLibrary関数またはFreeLibraryAndExitThread関数は、 参照カウントをデクリメントします。参照カウント がゼロに達したとき、またはプロセスが終了したときに( 参照カウントにかかわらず)、モジュールがモジュールをアンロードします。
したがって、モジュールを複数回読み込むと(FreeLibraryを呼び出すことなく)、同じハンドルが返されるように見えます。
DLLが既にロードされている場合、LoadLibrary
はライブラリのアドレスをメモリに戻すだけです。ただし、DllMain
は、2回目の読み込みが試行されたときにDLL_PROCESS_ATTACH
で再び呼び出されません。ライブラリの意味でのハンドルはメモリ位置に過ぎないので、2回目に取得する値は最初のものと同じにする必要があります。
LinuxのSOファイルについては、なぜ2度ロードするのかわかりません。しかし、他の誰かがあなたに適切な答えを与えるためにこれを体重測定する必要があります。
は、Linuxの場合dlopen(3)
manpageから、オブジェクトを共有:
同じライブラリがdlopen()
で再びロードされている場合は、同じファイル ハンドルがが返されます。
dl
ライブラリは ライブラリハンドルの参照カウントを維持し、そうdlclose()
が がに成功したdlopen()
として、その上のように何度も呼び出されるまでダイナミックライブラリが割り当て解除されていません。_init()
ルーチンが存在する場合は、一度だけ呼び出されます。 で後で呼び出すと、先にRTLD_LAZY
がロードされた ライブラリのシンボル解決が強制されることがあります。
これはプロセスごとに、またはすべてのプロセスに対してですか? – g19fanatic
@ g19fanatic - 同じプロセスです。 – cha0site
DLLの別のインスタンス(およびグローバル状態)が必要ですか? –
@DavidHeffernan可能かもしれませんが、それはLinuxでも可能です。私は、物事がいつもどのように働くのかをより詳しく調べようとしています。あなたが描写したことが可能なら、私はどのように知ることに興味があるでしょう。 –
オペレーティングシステムでも同じように動作します。 DLLの個別のインスタンスを取得するための汚いトリックがあります。新しいインスタンスが必要になるたびに、ファイルを一時的な場所にコピーし、一意の名前を付けます。そうすれば、新しいモジュールをロードするようにシステムを強制します。私は時々このテクニックを使用して、設計が貧弱でグローバルな状態を使用するためにスレッドセーフではないライブラリを回避しようとしました。 –