「Native-DLL」と「Managed-DLL」の探索方法は違う

Windowsにおいて、アセンブリはDLLで実装されています。

マネージドアプリ(EXE)からアセンブリ(DLL)を読み込む場合、一般的なWin32アプリケーションがEXEファイルからDLLを探索する手順とは異なるルールを採用しています。



参考までに、Win32のネイティブなDLLは、以下の順番で検索します(※1)。

  1. レジストリの「knowndll」リスト
  2. 実行ファイルのディレクトリ
  3. カレントディレクトリ
  4. システムディレクトリ
  5. Windowsディレクトリ
  6. 環境変数の「PATH」

しかし、最後まで名前に頼るというのが、安全ではないと考えられたため、「.NETのアセンブリ」ではより確実な方法な以下の順序に変更されました。

  1. 構成ファイル(app.config, machine.config等)の<codebase>要素
  2. 以前に読み込んだアセンブリのバインド履歴
  3. グローバルアセンブリキャッシュ(GAC)
  4. プローブによる検索

プローブによる検索の結果、結果的にカレントディレクトリにあるDLL(アセンブリ)を探す事になります。このため、ちゃんとした読み込み順序を認識している人が少ないようです。もちろん、プローブを利用することは曖昧なDLLを読み込む事になるため、安全なアプリを作成する妨げにもなります。

色々話しましたが、EXEと同じディレクトリにあっても最初に読み込まれるという動作は行わない。むしろ最後に近い段階である。

この違いだけ覚えておいてください。

参考までに、システムの中で重要なDLLは署名値と元にGACに格納されています。そのため、名前だけを同じにしても読み込ませる事はできません。

厳密に知りたい方は、MSDN内「.NET Framework 開発者ガイド」にある「ランタイムがアセンブリを検索する方法」も参考にしてください。



[MSDN] – DLL Hell の終焉

[MSDN] – LoadLibraryEx





※1 厳密に言えば、OSにより探索順序が異なります。最近のOSはPATHよりカレントディレクトリを優先します。



(05/12/16) 一部加筆。

Leave a Reply

Be the First to Comment!

Notify of
avatar
wpDiscuz