在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
最近完成了一个C++版本的对外sdk程序,其中有部分回调函数使用。 C++程序使用时没有异常,但是在C#环境下使用时出了点问题,简单总结下。 感谢博客:http://blog.csdn.net/songjinshi/article/details/8153635 帮助我解决了问题。
C++中的回调函数原型如下: typedef void (STDCALL *fCallback)(const char* csDetail, void *pUser); 其中有一个参数是char * ,就是字符指针,这里需要特别注意。
在C#中需要以委托完成相应回调操作,心路历程如下: 1,开始使用如下形式的委托函数: public delegate void MSGCALLBACK(ref byte pBuffer, UIntPtr pUser); 出现问题,回调函数仅能接收到一个字符,而非整个字符数组的值。
2,使用如下形式的委托函数: public delegate void MSGCALLBACK(ref byte[] pBuffer, UIntPtr pUser); 出现如1 的问题,回调函数仅能接收到一个字符,而非整个字符数组的值。
3,使用string代替byte数组,委托函数如下: public delegate void MSGCALLBACK(string pBuffer, UIntPtr pUser); 正常情况下接收数据均正常,但是在接收中文字符“面”是,出现异常,查看内存整个内存地址位置的值都异常了,如下: ,乱码问题是一个“面”子,相应xml格式中的“<”也不存在了,导致解析xml异常, 相应内存地址内容如下: 2f表示字符“/” 45是表示“E”,可以看到内存地址“/”前面的信息已经面目全非了, 这里具体什么原因确实没有找到,希望有大神可以帮忙解答。
4,最终正确的委托函数如下: 需要包含包 “using System.Runtime.InteropServices; public delegate void MSGCALLBACK([MarshalAs(UnmanagedType.LPArray, SizeConst = 8000)]byte[] pBuffer, UIntPtr pUser); 成功的接收回调消息并完成消息解析,没有出现任何异常。
解释如下: 在给c++传入数组参数时,必须得用 [MarshalAs(UnmanagedType.LPArray,SizeConst=8000)] 处理一下,相当于是告诉c++,c#传入的是一个长度为8000的数组类型,如果不写这句话的话,你回调函数接收到的参数将只有一条数据。 对于MarshalAs,MarshalAs属性指示如何在托管代码和非托管代码之间封送数据。 当 MarshalAsAttribute.Value 设置为 LPArray时,必须设置 SizeConst 以指示数组中的元素数。当需要区分字符串类型时,ArraySubType 字段可以选择包含数组元素的 UnmanagedType。此 UnmanagedType 只可用于作为结构中的字段的数组。而SizeConst则是指数组中的元素个数。
转载一个链接,用以帮助理解MarshalAs如何使用: http://blog.csdn.net/xiaobai1593/article/details/7025775
|
请发表评论