using System; using System.Reflection; using System.Runtime.InteropServices; namespace NaGet.InteropServices { /// /// DLLへの動的アクセスを行うクラス /// public class DllAccess : IDisposable { #region Win32 API [DllImport("kernel32.dll", CharSet=CharSet.Auto)] private extern static IntPtr LoadLibrary(string lpFileName); [DllImport("kernel32.dll")] private extern static bool FreeLibrary(IntPtr hModule); [DllImport("kernel32.dll", CharSet=CharSet.Ansi)] private extern static IntPtr GetProcAddress(IntPtr hModule, string lpProcName); #endregion private IntPtr hModule = IntPtr.Zero; /// /// コンストラクタ。DLLを読み込む /// /// /// DLLの名称。直接Win32APIのLoadLibraryにわたされる /// public DllAccess(string dllName) { hModule = LoadLibrary(dllName); if (hModule == IntPtr.Zero) { Exception innerEx = null; try { innerEx = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); } catch { } throw new DllNotFoundException("Failed to LoadLibrary " + dllName, innerEx); } } /// /// 関数をdelegateに変換して得る /// /// /// 関数名 /// /// /// 関数の型。戻り値のdelegateのタイプ /// /// /// delegateに変換された関数 /// public Delegate GetFunction(string strProcName, Type type) { IntPtr pFunc = GetProcAddress(hModule, strProcName); if (pFunc == IntPtr.Zero) { int result = Marshal.GetHRForLastWin32Error(); throw Marshal.GetExceptionForHR(result); } return Marshal.GetDelegateForFunctionPointer(pFunc, type); } /// /// DLLの読み込みを閉じる /// public void Dispose() { if (hModule != IntPtr.Zero) { FreeLibrary(hModule); hModule = IntPtr.Zero; } } } }