C#调用C/C++ DLL 参数传递和回调函数的总结
Posted lonelyxmas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#调用C/C++ DLL 参数传递和回调函数的总结相关的知识,希望对你有一定的参考价值。
原文:C#调用C/C++ DLL 参数传递和回调函数的总结
Int型传入:
Dll端:
extern?"C"?__declspec(dllexport)?int?Add(int?a,?int?b) { ????return?a+b; } |
C#端:
[DllImport("aeClient2.0.dll",?CallingConvention?=CallingConvention.Cdecl)] ?public?static?extern?unsafe?int?Add(int?a,?int?b); |
?
Int型传入传出:
Dll端:
extern?"C"?__declspec(dllexport)?int?Add(int?*a,?int*?b) { ??? *a?= 2; ??? *b?= 3; ????return?add(2, 3); } |
C#端
[DllImport("aeClient2.0.dll",?CallingConvention?=CallingConvention.Cdecl)] ?public?static?extern?unsafe?int?Add(int?a,?int?b); |
?
String传入:
Dll端:
extern?"C"?__declspec(dllexport)?BOOL?sendMessage(char*?msg) { ????CString?str?=?msg; ??? ::AfxMessageBox(str.GetBuffer(0)); ????return?3; } |
C#端:
[DllImport("aeClient1.1.dll",?CallingConvention?=CallingConvention.Cdecl)] public?static?extern?int?sendMessage(string?msg); ? string?strin?=?"llqq哈t哈t哈t呵?呵?"; sendMessage(strin); |
?
String型传入传出:
Dll端:
extern?"C"?__declspec(dllexport)?BOOL?GetErrorMessage(char?*szErrorMessage?) { ????CString?str?=?szErrorMessage; ????AfxMessageBox(str); ????char?tmp[] =?"nm世界和平nmnm"; ????strcpy(szErrorMessage,tmp); ????return?3; } |
C#端:
[DllImport("aeClient1.1.dll",?CallingConvention?=CallingConvention.Cdecl)] public?static?extern?int?GetErrorMessage(StringBuilder?msg); ? StringBuilder?buf?=?new?StringBuilder(1024);//指定的buf大小必须大于传入的字符长度 buf.Append("abc中国人"); int?outdata?=?GetErrorMessage(buf, 1);? string?strout?=?buf.ToString(); |
?
结构体传入:
Dll端:
class?NET_INFO_STRUCT? {? public: ????DWORD?nDurationTime;?//持?续?时o?à间??? ????double?nReceiveByte;?//接¨?收o?字á?节¨2? ????double?nSendByte;???//发¤?é送¨a字á?节¨2? ????WORD?word; ????char?buf[200]; ????FILETIME?time; }; extern?"C"?__declspec(dllexport)?BOOL?NetGetConnectDetail(NET_INFO_STRUCT?lpNetInfo) { ??? ::AfxMessageBox(lpNetInfo.buf); ????return?3; } ? |
C#端
public?struct?FILETIME ??? { ????????public?uint?high; ????????public?uint?low; ??? } ????public?struct?NET_INFO_STRUCT? ??? {? ????????public?uint?nDurationTime;?//持?续?时o?à间??? ????????public?double?nReceiveByte;?//接¨?收o?字á?节¨2? ????????public?double?nSendByte;???//发¤?é送¨a字á?节¨2? ????????public?ushort?ush; ??????? [MarshalAs(UnmanagedType.ByValTStr,?SizeConst?= 200)] ????????public?string?str; ????????public?FILETIME?time; ??? } ; [DllImport("aeClient1.1.dll",?CallingConvention?=CallingConvention.Cdecl)] public?static?extern?unsafe?int?NetGetConnectDetail(NET_INFO_STRUCT?lpNetInfo); ? NET_INFO_STRUCT?stru?=?new?NET_INFO_STRUCT(); ????????????stru.nDurationTime?= 8989; ????????????stru.nReceiveByte?= 89.89; ????????????stru.nSendByte?= 89.8900; ????????????stru.ush?= 56; ????????????stru.str?=?"来来去去ypfisja"; ????????????stru.time.high?= 24; ????????????stru.time.low?= 17; ????????????NetGetConnectDetail(stru); |
?
?
结构体数组传出:
Dll端:
struct?UIM_BOOK_STRUCT? {? ????int?UimIndex;? ????char?szName[15];? ????char?szPhone[21];? };? extern?"C"?__declspec(dllexport)?int?ReadUimAllBook(UIM_BOOK_STRUCT?lpUimBookItem[],intnMaxArraySize) { ????lpUimBookItem[0].UimIndex?= 345; ????strcpy(lpUimBookItem[0].szName?,?"dsd"); ????strcpy(lpUimBookItem[0].szPhone?,?"bbbb"); ? ????lpUimBookItem[1].UimIndex?= 111; ????strcpy(lpUimBookItem[1].szName?,?"ddddd"); ????strcpy(lpUimBookItem[1].szPhone?,?"vvvvvv"); ? ????lpUimBookItem[2].UimIndex?= 2222; ????strcpy(lpUimBookItem[2].szName?,?"d3343434sd"); ????strcpy(lpUimBookItem[2].szPhone?,?"bbbfggfggggfgb"); ? ????return?4; } |
C#端:
[StructLayout(LayoutKind.Sequential,?CharSet?=?CharSet.Ansi)] public?struct?UIM_BOOK_STRUCT { ????????public?int?UimIndex; ??????? [MarshalAs(UnmanagedType.ByValTStr,?SizeConst?= 15)] ????????public?string?szName; ??????? [MarshalAs(UnmanagedType.ByValTStr,?SizeConst?= 21)] ????????public?string?szPhone; }; [DllImport("aeClient1.1.dll",?CallingConvention?=CallingConvention.Cdecl)] public?static?extern?unsafe?int?ReadUimAllBook([Out]?UIM_BOOK_STRUCT[]?lpUimBookItem,?intnMaxArraySize); ? UIM_BOOK_STRUCT[]?p?=?new?UIM_BOOK_STRUCT[20]; int?rets?=?ReadUimAllBook(p,?p.Length); |
?
回调函数传递字符串:
Dll端:
typedef?int?(*pfCallBack)(int?a,?char?b[]); pfCallBack?CallBackfun?=?NULL; ? extern?"C"?__declspec(dllexport)?void?SetCB(int?(*pfCallBack)(int?a,?charb[]))? {? ????CallBackfun?=?pfCallBack;? }? char?ch[100]; extern?"C"?__declspec(dllexport)?void?callTheCB() { ????int?a?= 4; ????memset(ch,?‘ ‘, 100); ????strcpy(ch,?"aabbcc"); ????CallBackfun(a,?ch); } |
C#端
//定?§义°?一°?个?委?¥托aD,ê?其?返¤|ì回?类¤¨¤型¨a和¨a形?参?与??方¤?法¤?§体??的ì?返¤|ì回?类¤¨¤型¨a形?参?一°?致?? [UnmanagedFunctionPointer(CallingConvention.Cdecl)]//一°?定?§要°a加¨?上|?这a句?,ê?要°a不?然¨?C#中D的ì?回?调ì??函?¥数oy只?要°a被à?调ì??用??一°?次??,ê?程¨?序¨°就¨a异°¨?常?ê退a?出?了¢?!ê?!ê?!ê?? public?delegate?int?callBackHandler(int?a, [MarshalAs(UnmanagedType.LPStr)]StringBuilder?b); callBackHandler?fun;//声|¨′明??一°?个?委?¥托aD变à?量¢?? [DllImport("xxx.dll",?CallingConvention?=CallingConvention.Cdecl)] public?static?extern?unsafe?void?SetCB(callBackHandler?fun1); [DllImport("xxx.dll",?CallingConvention?=CallingConvention.Cdecl)] public?static?extern?unsafe?void?callTheCB(); ? int?localFun(int?a, [MarshalAs(UnmanagedType.LPStr)]StringBuilder?b) { ????????MessageBox.Show(b.ToString()); ????????return?0; } ? fun?=?new?callBackHandler(localFun);//给?委?¥托aD变à?量¢?赋3值|ì??? SetCB(fun);//用??委?¥托aD当ì?à做á?函?¥数oy指?针?作á??为a参?数oy传??入¨? callTheCB(); |
?
回调函数传递结构体:
Dll端:
struct?REvent { ????REvent(ONEVENTSTRUCT*?pEVENTSTRUCT); ????WORD????m_ChangeMask; ????WORD????m_State; ????char?m_Source[200]; }; ? typedef?void?(*pfCallBackEvent)(REvent?eve/*, char m_Source[]*/); pfCallBackEvent?CallBackfunEvent?=?NULL; extern?"C"?__declspec(dllexport)?void?SetCBEvent(void?(*pfCallBackEvent)(REvent?eve/*, char m_Source[]*/))? { ????CallBackfunEvent?=?pfCallBackEvent;? }? void?callCBEvent(REvent?eve/*, char m_Source[]*/) { ????CallBackfunEvent(eve/*, m_Source*/); } ? //调用回调函数 callCBEvent(*pREvent/*, pEvent->m_Message.GetBuffer(0)*/); |
C#端:
[StructLayout(LayoutKind.Sequential,?CharSet?=?CharSet.Ansi)] ????????public?struct?REvent ????????{ ????????????public?ushort?m_ChangeMask; ????????????public?ushort?m_State; ????????????[MarshalAs(UnmanagedType.ByValTStr,?SizeConst?= 200)] ????????????public?string?m_Source; ????????}; ? ????????[StructLayout(LayoutKind.Sequential,?CharSet?=?CharSet.Ansi)]//可¨|以°?指?定?§编ਤ码?类¤¨¤型¨a ????????public?struct?EventSourceTag ????????{ ????????????//[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)] ????????public?IntPtr?name; ????????}; ????????//定?§义°?一°?个?委?¥托aD,ê?其?返¤|ì回?类¤¨¤型¨a和¨a形?参?与??方¤?法¤?§体??的ì?返¤|ì回?类¤¨¤型¨a形?参?一°?致?? ????????[UnmanagedFunctionPointer(CallingConvention.Cdecl,?CharSet?=?CharSet.Ansi)]//一°?定?§要°a加¨?上|?这a句?,ê?要°a不?然¨?C#中D的ì?回?调ì??函?¥数oy只?要°a被à?调ì??用??一°?次??,ê?程¨?序¨°就¨a异°¨?常?ê退a?出?了¢?!ê?!ê?!ê? ????????public?delegate?void?CBEventHandle(REvent?eve/*, [MarshalAs(UnmanagedType.LPStr)]StringBuilder source*/); ????????CBEventHandle?cbFun;//声|¨′明??一°?个?委?¥托aD变à?量¢?? ????????[DllImport("xxx.dll",?CharSet?=?CharSet.Ansi,?CallingConvention?=?CallingConvention.Cdecl)] ????????public?static?extern?unsafe?void?SetCBEvent(CBEventHandle?fun); ? void?CBEvent(REvent?eve/*, [MarshalAs(UnmanagedType.LPStr)]StringBuilder source*/) { ????????//string str = Marshal.PtrToStringAnsi(source); ????????//string str = System.Text.Encoding.Default.GetString(source); ????????MessageBox.Show(eve.m_Message.ToString()); } ? cbFun?=?new?CBEventHandle(CBEvent); SetCBEvent(cbFun); |
以上是关于C#调用C/C++ DLL 参数传递和回调函数的总结的主要内容,如果未能解决你的问题,请参考以下文章
如何从 C# 调用具有 void* 回调和对象参数的 C++ Dll 中的函数
将带有参数的 c# 回调方法传递给 c++ dll 会导致 System.ExecutionEngineException