Dec
2
前文"C#调用C++函数入口点的问题"说了一点关于使用DLLImport进行导入函数的事. C#调用C++的函数其实不止这一种方法, 还有一种方法是用delegate申明函数委托进行调用,这种方法略显麻烦,但是可以进行回调并应用指针.
在C#中,首先先要定义一个类,用来把DLL中函数地址转换成委托:
HiddenCopy Code To Clipboard
- 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声明函数:
HiddenCopy Code To Clipboard
- delegate void _amDBRSetThermoModel(int mid, ref int errid);
再然后, 自己写个private的函数封装DLL中的函数, hModule()函数的作用是取得DLL的地址,用在多个输出函数中
HiddenCopy Code To Clipboard
- 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;
- }
- }
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被调用时, 断点标记才会变成实心并被激活.




