以下のプログラムはUser32.dllにある「MessageBox」関数を呼び出すサンプルプログラムです。
using MMFrame.Diagnostics;
public class User32 : UnManagedDll
{
private class Functions
{
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Ansi)]
public delegate int MessageBox(IntPtr hwnd, string text, string caption, uint type);
}
public User32(string dllPath) : base(dllPath) {}
public int MessageBox(IntPtr hwnd, string text, string caption, uint type)
{
return GetProcAddress()(hwnd, text, caption, type);
}
}
//使う側
using(User32 user32 = new User32("User32.dll"))
{
user32.MessageBox(IntPtr.Zero, "テキスト", "キャプション", 0x4);
}
http://note.chiebukuro.yahoo.co.jp/detail/n350146
► スポイラーを表示
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.IO;
namespace MMFrame.Diagnostics
{
///
/// アンマネージ DLL の遅延バインディングに関するクラス
///
public class UnManagedDll : IDisposable
{
private static class NativeMethods
{
///
/// 指定された実行可能モジュールを、呼び出し側プロセスのアドレス空間内にマップします。
///
/// 実行可能モジュールの名前を保持する null で終わる文字列へのポインタ
/// モジュールのハンドル
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", BestFitMapping = false, ThrowOnUnmappableChar = true)]
public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
///
/// ダイナミックリンクライブラリ(DLL)が持つ、指定されたエクスポート済み関数のアドレスを取得します。
///
/// 希望の関数を保持する DLL モジュールのハンドル
/// 関数名を保持する null で終わる文字列へのポインタ
/// DLL のエクスポート済み関数のアドレス
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress", BestFitMapping = false, ThrowOnUnmappableChar = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)]string lpProcName);
///
/// ロード済みのダイナミックリンクライブラリ(DLL)モジュールの参照カウントを 1 つ減らします。
/// 参照カウントが 0 になると、モジュールは呼び出し側プロセスのアドレス空間からマップ解除され、そのモジュールのハンドルは無効になります。
///
/// ロード済みの DLL モジュールのハンドル
/// 関数が成功した場合は 0 以外
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FreeLibrary(IntPtr hModule);
}
///
/// DLL のパスを取得、設定します。
///
public string DllPath
{
get;
set;
}
///
/// アンマネージ DLL が使用可能かどうかを取得、設定します。
///
public bool IsAvailable
{
get;
set;
}
///
/// リソースが解放されているかどうかを取得、設定します。
///
protected bool Disposed
{
get;
set;
}
///
/// DLL モジュールのハンドルを取得、設定します。
///
private IntPtr ModuleHandle
{
get;
set;
}
///
/// 関数名とその のコレクションを取得、設定します。
///
private Dictionary Functions
{
get;
set;
}
///
/// オブジェクトを生成します。
///
public UnManagedDll()
{
Initialize();
}
///
/// オブジェクトを生成します。
///
/// に DLL が存在しない場合、スローされます。
/// DLL のパス
public UnManagedDll(string dllPath)
{
Initialize();
this.Load(dllPath);
}
///
/// のデストラクタ
///
~UnManagedDll()
{
Dispose(false);
}
///
/// アンマネージ DLL を読み込みます。
///
/// に DLL が存在しない場合、スローされます。
/// DLL のパス
/// 読み込みが成功した場合は true
public bool Load(string dllPath)
{
this.DllPath = dllPath;
if (!File.Exists(this.DllPath))
{
throw new FileNotFoundException(this.DllPath + " は存在しません。");
}
this.ModuleHandle = NativeMethods.LoadLibrary(this.DllPath);
this.IsAvailable = true;
return this.IsAvailable;
}
///
/// 指定されたエクスポート済み関数を取得します。
///
/// DLL が存在しない場合、スローされます。
/// DLL に指定された関数が存在しない場合、スローされます。
/// エクスポート済み関数の定義
/// エクスポート済み関数
public T GetProcAddress() where T : class
{
if (!this.IsAvailable)
{
throw new FileNotFoundException(this.DllPath + " は存在しません。");
}
string funcName = typeof(T).Name;
if (!this.Functions.ContainsKey(funcName))
{
IntPtr procAddress = NativeMethods.GetProcAddress(this.ModuleHandle, funcName);
if (procAddress == System.IntPtr.Zero || procAddress == null)
{
throw new NotImplementedException(this.DllPath + " に " + funcName + " は見つかりません。");
}
this.Functions[funcName] = Marshal.GetDelegateForFunctionPointer(procAddress, typeof(T));
}
return this.Functions[funcName] as T;
}
///
/// 割り当てられたリソースを解放します。
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// 割り当てられたリソースを解放します。
///
/// マネージドリソースの解放をする場合は true
protected void Dispose(bool disposing)
{
if (this.Disposed)
{
return;
}
this.Disposed = true;
if (disposing)
{
this.Functions = null;
}
if (this.ModuleHandle != IntPtr.Zero || this.ModuleHandle != null)
{
NativeMethods.FreeLibrary(this.ModuleHandle);
this.ModuleHandle = IntPtr.Zero;
}
}
///
/// 初期化します。
///
private void Initialize()
{
this.IsAvailable = false;
this.Disposed = false;
this.Functions = new Dictionary();
this.ModuleHandle = IntPtr.Zero;
}
}
}