使用DLLImport进行导入函数的事. C#调用C++的函数其实不止这一种方法, 还有一种方法是用delegate申明函数委托进行调用,这种方法略显麻烦,但是可以进行回调并应用指针.
在C#中,首先先要定义一个类,用来把DLL中函数地址转换成委托:
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">Get DLL handle by LoadLibrary</param> ///<param name="functionName">Unmanaged function name</param> ///<param name="t">ManageR type对应的委托类型</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); } }
然后, 用delegate声明函数:
delegate void _amDBRSetThermoModel(int mid, ref int errid);
再然后, 自己写个private的函数封装DLL中的函数, hModule()函数的作用是取得DLL的地址,用在多个输出函数中
private int hModule() { int _hModule = DLLWrapper.LoadLibrary(DLLPATH); if (_hModule == 0) { return 0; } return _hModule; } private void amDBRInitialize() { try { _amDBRInitialize amf = (_amDBRInitialize)DLLWrapper.GetFunctionAddress(hModule(), "amDBRInitialize", typeof(_amDBRInitialize)); amf(); } catch (Exception e) { throw e; } }