• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

c#调用c++带有回调函数方法的实现

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

最近完成了一个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

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Oraclee事务处理以及在c#中使用oracle的事务处理【转载】发布时间:2022-07-14
下一篇:
C#通过com端口获取sap数据(sharepoint)发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap