c#调用c++带有回调函数方法的实现
最近完成了一个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);
正常情况下接收数据均正常,但是在接收中文字符“面”是,出现异常,查看内存整个内存地址位置的值都异常了,如下:
相应内存地址内容如下:
这里具体什么原因确实没有找到,希望有大神可以帮忙解答。
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
c#调用c++带有回调函数方法的实现的更多相关文章
- Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数
Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数~~~ 呵呵... 看着有点晕.. 再解释一下就是 在Unity中 使用 C# 调用 C++ 写的 DLL, 但是在 ...
- Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程
Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...
- 基于委托的C#异步编程的一个小例子 带有回调函数的例子
我创建的是一个winform测试项目:界面如下: 设置: 下面是代码: using System; using System.Collections.Generic; using System.Com ...
- 浅尝辄止——在C++中调用C#的回调函数——COM方式
这种方式比较简单,给大家分享一下,同时讲一下SafeArray内定义结构体的方法 1. 需求描述 需求是这样的,C++代码和C#代码相互通信(C++一般做服务,C#做客户端),C++一侧准备好数据,然 ...
- 微信小程序如何把接口调用成功的回调函数返回的参数return出去?(promise就可以解决)
举个栗子//获取应用实例 //const app = getApp() //const util = require('../../utils/util.js') //const sign = uti ...
- wx: wx.showModal 回调函数中调用自定义方法
一.在回调函数中调用自定义方法: 回调函数中不能直接使用this,需要在外面定义 var that = this 然后 that.自定义的方法.如下: //删除 onDelete: function ...
- [转]理解与使用Javascript中的回调函数
在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...
- 【JavaScript】理解与使用Javascript中的回调函数
在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...
- Delphi回调函数及其使用
Delphi回调函数及其使用 1 回调函数的概述 回调函数是这样一种机制:调用者在初始化一个对象(这里的对象是泛指,包括OOP中的对象.全局函数等)时,将一些参数传递给对象,同时将一个调用者可以访问的 ...
随机推荐
- hibernate 悲观锁乐观锁
悲观锁和乐观锁是:在事务隔离机制中设置了ReadCommited的情况下,两种可以避免不可重复读的方式. 设置成读已提交是考虑到安全和处理速度,保证并发效率,但是在这个情况下仍然需要避免不可重复读 ...
- Hive学习 系列博客
原 Hive作业优化 原 Hive学习六:HIVE日志分析(用户画像) 原 Hive学习五--日志案例分析 原 Hive学习三 原 Hive学习二 原 Hive学习一 博客来源,https://blo ...
- 生产环境中 Ngx_lua 使用技巧和应用的范例
生产环境中 Ngx_lua 使用技巧和应用的范例 时间 -- :: 51CTO技术博客 原文 http://rfyiamcool.blog.51cto.com/1030776/1252501 主题 L ...
- Git merge two repositories (ZZ)
转自 https://stackoverflow.com/questions/2428137/how-to-rebase-one-git-repository-onto-another-one If ...
- C# 子类实例化过程
刚研究了一下C#子类实例化的过程. 首先我遇到了如下一个问题: 有类A,里面写了一个有参的构造函数,并没有提供默认的无参构造函数.现在类B继承了类A,没有写任何的构造函数. 这时如果想实例化类B就会产 ...
- 我的 Android 开发实战经验总结
我的 Android 开发实战经验总结 字数4440 阅读5137 评论43 喜欢250 曾经一直想写一篇总结 Android 开发经验的文章,预计当时的我还达不到某种水平,所以思路跟不上,下笔又捉襟 ...
- ListView中pointToPosition()方法使用具体演示样例
MainActivity例如以下: package cc.testpointtoposition; import java.util.ArrayList; import java.util.HashM ...
- Spring MVC生成RSS源
下面的示例演示如何使用Spring Web MVC框架生成RSS源. 首先使用Eclipse IDE,并按照以下步骤使用Spring Web Framework开发基于动态表单的Web应用程序: 创建 ...
- jsp a href怎么传参数?
jsp中超链接传值使用键值对格式,多个键值对之间用&分隔,即<a href="show.jsp?name=tom&pass=123&score=78,5&quo ...
- 关于JAVA编译时找不到自定义包的问题
这两天照网上的教程,学习JSP/SERVLET/JAVABEAN,写了几个JAVA文件,目录放在TOMCAT的WEBAPPS下面,通过javac编译时,老提示找不到指定的包: 下图是我的目录路径: 通 ...