public class DLLWrapper { ///<summary> /// API LoadLibrary ///</summary> [DllImport("Kernel32")] public static extern int LoadLibrary(String funcname);
///<summary> /// API GetProcAddress ///</summary> [DllImport("Kernel32")] public static extern int GetProcAddress(int handle, String funcname);
///<summary> /// API FreeLibrary ///</summary> [DllImport("Kernel32")] public static extern int FreeLibrary(int handle);
///<summary> ///通过非托管函数名转换为对应的委托, by jingzhongrong ///</summary> ///<param name="dllModule">通过LoadLibrary获得的DLL句柄</param> ///<param name="functionName">非托管函数名</param> ///<param name="t">对应的委托类型</param> ///<returns>委托实例,可强制转换为适当的委托类型</returns> public static Delegate GetFunctionAddress(int dllModule, string functionName, Type t) { int address = GetProcAddress(dllModule, functionName); if (address == 0) return null; else return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t); }
///<summary> ///将表示函数地址的IntPtr实例转换成对应的委托, by jingzhongrong ///</summary> public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t) { if (address == IntPtr.Zero) return null; else return Marshal.GetDelegateForFunctionPointer(address, t); }
///<summary> ///将表示函数地址的int转换成对应的委托,by jingzhongrong ///</summary> public static Delegate GetDelegateFromIntPtr(int address, Type t) { if (address == 0) return null; else return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t); } }
通过这个类,我们这样调用DLL:
1、声明相应的委托(正确声明很重要,否则不能调用成功,后面有详细介绍)。
2、加载DLL: int hModule = DLLWrapper.LoadLibrary(dllFilePath); if (hModule == 0) return false;
使用LayoutKind指定结构中成员的布局顺序,一般可以使用Sequential: [StructLayout(LayoutKind.Sequential)] struct StructVersionInfo { public int MajorVersion; public int MinorVersion; } 另外,如果单独使用内部类型没有另外使用到字符串、结构、类,可以将结构在C#中声明为class: [StructLayout(LayoutKind.Sequential)] class StructVersionInfo { public int MajorVersion; public int MinorVersion; }
对应C++中的声明: typedef struct _VERSION_INFO { int MajorVersion; int MinorVersion; } VERSION_INFO, *PVERSION_INFO;