Dec 2

前文"C#调用C++函数入口点的问题"说了一点关于使用DLLImport进行导入函数的事. C#调用C++的函数其实不止这一种方法, 还有一种方法是用delegate申明函数委托进行调用,这种方法略显麻烦,但是可以进行回调并应用指针.

在C#中,首先先要定义一个类,用来把DLL中函数地址转换成委托:

HiddenCopy Code To Clipboard
  1. public class DLLWrapper
  2. {
  3. ///<summary>
  4. /// API LoadLibrary
  5. ///</summary>
  6. [DllImport("Kernel32")]
  7. public static extern int LoadLibrary(String funcname);
  8.  
  9. ///<summary>
  10. /// API GetProcAddress
  11. ///</summary>
  12. [DllImport("Kernel32")]
  13. public static extern int GetProcAddress(int handle, String funcname);
  14.  
  15. ///<summary>
  16. /// API FreeLibrary
  17. ///</summary>
  18. [DllImport("Kernel32")]
  19. public static extern int FreeLibrary(int handle);
  20.  
  21. ///<summary>
  22. ///通过非托管函数名转换为对应的委托, by jingzhongrong
  23. ///</summary>
  24. ///<param name="dllModule">Get DLL handle by LoadLibrary</param>
  25. ///<param name="functionName">Unmanaged function name</param>
  26. ///<param name="t">ManageR type对应的委托类型</param>
  27. ///<returns>委托实例,可强制转换为适当的委托类型</returns>
  28. public static Delegate GetFunctionAddress(int dllModule, string functionName, Type t)
  29. {
  30. int address = GetProcAddress(dllModule, functionName);
  31. if (address == 0)
  32. return null;
  33. else
  34. return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
  35. }
  36.  
  37. ///<summary>
  38. ///将表示函数地址的IntPtr实例转换成对应的委托, by jingzhongrong
  39. ///</summary>
  40. public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t)
  41. {
  42. if (address == IntPtr.Zero)
  43. return null;
  44. else
  45. return Marshal.GetDelegateForFunctionPointer(address, t);
  46. }
  47.  
  48. ///<summary>
  49. ///将表示函数地址的int转换成对应的委托,by jingzhongrong
  50. ///</summary>
  51. public static Delegate GetDelegateFromIntPtr(int address, Type t)
  52. {
  53. if (address == 0)
  54. return null;
  55. else
  56. return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
  57. }
  58. }

然后, 用delegate声明函数:

HiddenCopy Code To Clipboard
  1. delegate void _amDBRSetThermoModel(int mid, ref int errid);

再然后, 自己写个private的函数封装DLL中的函数, hModule()函数的作用是取得DLL的地址,用在多个输出函数中

HiddenCopy Code To Clipboard
  1. private int hModule()
  2. {
  3. int _hModule = DLLWrapper.LoadLibrary(DLLPATH);
  4. if (_hModule == 0)
  5. {
  6. return 0;
  7. }
  8. return _hModule;
  9. }
  10.  
  11. private void amDBRInitialize()
  12. {
  13. try
  14. {
  15. _amDBRInitialize amf = (_amDBRInitialize)DLLWrapper.GetFunctionAddress(hModule(), "amDBRInitialize", typeof(_amDBRInitialize));
  16. amf();
  17. }
  18. catch (Exception e)
  19. {
  20. throw e;
  21. }
  22. }

 

Tags: , , , ,
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]