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;
}
}
}
}