Win32 API LoadLibraryを使用して同じ DLL を 3 回続けてロードすると、3 つの異なるハンドルが返され、各ライブラリの関数はすべて異なるアドレスを持つ必要がありますか? (または、何か「賢い」ことを行い、dll がプロセス用に既にロードされているかどうかを検出し、同じモジュールを指すだけですか?)
3 に答える
それは賢いことをします。Windows は、LoadLibrary を通じて読み込まれた各 DLL の参照カウントを保持します。そのため、対応する LoadLibrary 呼び出しごとに FreeLibrary を 1 回呼び出す必要があります。最初に DLL を解放しないと仮定すると、LoadLibrary を呼び出すたびに同じハンドルが返されます。
FreeLibrary の MSDN ドキュメントから:
各プロセスは、読み込まれた各ライブラリ モジュールの参照カウントを維持します。この参照カウントは、LoadLibrary が呼び出されるたびに増加し、FreeLibrary が呼び出されるたびに減少します。
それらが同じDLLである場合、それは再度ロードされません。
http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx
「指定されたモジュールが呼び出しプロセス用にまだロードされていないDLLの場合、システムはDLLのDllMain関数をDLL_PROCESS_ATTACH値で呼び出します。DllMainがTRUEを返す場合、LoadLibraryはモジュールへのハンドルを返します。DllMainがFALSEを返す場合、システムはプロセスアドレススペースからDLLをアンロードすると、LoadLibraryはNULLを返します。DllMainからLoadLibraryを呼び出すのは安全ではありません。詳細については、DllMainの「備考」セクションを参照してください。
「lpFileNameにパスが含まれておらず、同じベース名と拡張子を持つロードされたモジュールが複数ある場合、関数は最初にロードされたモジュールへのハンドルを返します。」
いいえ、そうではありません。これを回避するには、.dll を一時ファイルにコピーし (.dll をロードするのに必要な回数だけ)、完了したらファイルを削除します。