イティブ DLL の関数を呼び出したい,の巻
2003/11/17 新規

唐突ですが、以下のサイトが非常に有用です。

 

ネイティブ(Win32)DLL で定義された関数を呼び出すのは(引数がなければ)簡単で、すぐにできます。 ですが、その DLL が一体いつ読み込まれているのかは不明です。

そもそも、VC++ ではこんな感じで DLL をロードしてると思います。

  1. LoadLibrary() 関数で DLL を読み込む
  2. 自動的に対象 DLL の DllMain() 関数(引数:DLL_PROCESS_ATTACH)が呼ばれる
  3. 最初の手順で得られる DLL のインスタンスを使って、任意の関数を呼ぶ
  4. DLL が不要になったら、FreeLibrary() 関数で開放する
  5. 自動的に対象 DLL の DllMain() 関数(引数:DLL_PROCESS_DETACH)が呼ばれる
実際に関数を呼ぶには、さらにその関数のアドレスを取得する作業も必要です。

かわって、問題の C# では。
例えば こんな感じに、使用する DLL の関数を "属性付き" で宣言してしまいます。 すると あとは何も考えず使い放題です。
例1

[DllImport("kernel32.dll")]
public static extern bool Beep(uint dwFreq,uint dwDuration);

流れを書けば、こんな感じになると思います。

  1. 外部メソッドとして、使用したい DLL の関数を "属性付き" で宣言する
  2. なにも考えずに そのまま外部メソッドを呼ぶ
  3. 初回のメソッド・コールでのみ DllMain() 関数(引数:DLL_PROCESS_ATTACH)が呼ばれる
  4. アプリケーション終了時に DllMain() 関数(引数:DLL_PROCESS_DETACH)が呼ばれる
つまり VC++ でいうところの LoadLibrary() 関数と FreeLibrary() 関数が、暗黙的に呼ばれているようです。

そんなのはイヤで、「明示的に DllMain() 関数を呼び出たい!」という人には、このサイトがお勧めです。

要約すると、「C# に“Win32 DLL を読み込む明示的な手法”がなければ、Win32 API を利用してしまえ!」という感じです。
例2

[DllImport("kernel32")]
public extern static int LoadLibrary(string lpLibFileName);

[DllImport("kernel32")]
public extern static bool FreeLibrary(int hLibModule);

[DllImport("kernel32",CharSet=CharSet.Ansi)]
public extern static int GetProcAddress(int hModule,string lpProcName);
ホントに、LoadLibrary() 関数などを使ってしまう手法を取っていました。 これで VC++ とほとんど同じ手続きで、DLL とその関数群を扱えます。
海外の人は、発想がスゴイですね。


戻る