**
使用C#动态加载DLL文件
**
1.首先用到kernel32.dll API函数,对于C#来说调用windows API 还是蛮简单的事件。只需要声明一下就可以了。
//加载DLL
[DllImport("kernel32.dll", SetLastError = true ,CharSet = CharSet.Auto)]
private extern static IntPtr LoadLibrary(string path);
//获取函数地址
[DllImport("kernel32.dll",SetLastError =true)]
private extern static IntPtr GetProcAddress(IntPtr lib, string funcName);
//释放相应的库
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);
//获取错误信息
[DllImport("Kernel32.dll")]
public extern static int FormatMessage(int flag, ref IntPtr source, int msgid, int langid, ref string buf, int size, ref IntPtr args);
2.需要知道你调用DLL里面的函数名称,以下是主要的三个函数。
/// <summary>
/// 构造函数
/// </summary>
/// <param name="dll_path">DLL路径</param>
public DllInvoke(string dll_path)
{
if (File.Exists(dll_path))
{
hLib = LoadLibrary(dll_path);
}
}
/// <summary>
/// 析构函数
/// </summary>
~DllInvoke()
{
FreeLibrary(hLib);
}
/// <summary>
/// 将要执行的函数转换为委托
/// </summary>
/// <param name="APIName">函数名称</param>
/// <param name="t">类型</param>
/// <returns></returns>
public Delegate Invoke(string APIName, Type t)
{
IntPtr api = GetProcAddress(hLib, APIName);
return Marshal.GetDelegateForFunctionPointer(api, t);
}
我将调用API的函数封装成类。
在调试的过程遇到加载不成功的情况,然后想到获取错误代码,然后从错误代码里面查找到原因。函数如下:
/// <summary>
/// 获取系统错误信息描述
/// </summary>
/// <param name="errCode">系统错误码</param>
/// <returns></returns>
public string GetSysErrMsg(int errCode)
{
IntPtr tempptr = IntPtr.Zero;
string msg = null;
FormatMessage(0x1300, ref tempptr, errCode, 0, ref msg, 255, ref tempptr);
return msg;
}
/// <summary>
/// 获取最近一个win32Error
/// </summary>
/// <returns></returns>
public int GetWin32ErrorCode()
{
return Marshal.GetLastWin32Error();
}
3.在程序中调用DLL的例子
定义委托:
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
private delegate int GETMD5(string str, byte[] pData);
实例化对象:
DllInvoke dll = new DllInvoke(System.AppDomain.CurrentDomain.BaseDirectory + "\\md5.dll");
//根据函数名获取函数委托对象 _fnMD5@8函数的别名
GETMD5 get_md5 = (GETMD5)dll.Invoke("_fnMD5@8", typeof(GETMD5));
//temp输出对象
get_md5(“123456789”, temp);