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: , , , ,
Dec 2

C++编写的DLL函数被C#所写的应用程序调用, 使用VS2005进行DEBUG时, 所设的断点无效, 系统信息显示"The breakpoint will not currently be hit. No symbols have been loaded for this document."

查阅无数资料, 大多写的是关于PDB文件如何如何, 试过都没有作用.

后来发现,其实只要在project properties中更改一下debugger type 就可以了. 如下图所示, 把debugger type从AUTO改到MIXED, 断点就可以用了, 不过要注意改完并DEBUG刚开始时, 断点还是空心的, 只有当DLL被调用时, 断点标记才会变成实心并被激活.

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