最近完成了一个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++带有回调函数方法的实现的更多相关文章

  1. Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数

    Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数~~~    呵呵... 看着有点晕.. 再解释一下就是 在Unity中 使用 C# 调用 C++ 写的 DLL, 但是在 ...

  2. Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程

    Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...

  3. 基于委托的C#异步编程的一个小例子 带有回调函数的例子

    我创建的是一个winform测试项目:界面如下: 设置: 下面是代码: using System; using System.Collections.Generic; using System.Com ...

  4. 浅尝辄止——在C++中调用C#的回调函数——COM方式

    这种方式比较简单,给大家分享一下,同时讲一下SafeArray内定义结构体的方法 1. 需求描述 需求是这样的,C++代码和C#代码相互通信(C++一般做服务,C#做客户端),C++一侧准备好数据,然 ...

  5. 微信小程序如何把接口调用成功的回调函数返回的参数return出去?(promise就可以解决)

    举个栗子//获取应用实例 //const app = getApp() //const util = require('../../utils/util.js') //const sign = uti ...

  6. wx: wx.showModal 回调函数中调用自定义方法

    一.在回调函数中调用自定义方法: 回调函数中不能直接使用this,需要在外面定义 var that = this 然后 that.自定义的方法.如下: //删除 onDelete: function ...

  7. [转]理解与使用Javascript中的回调函数

    在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...

  8. 【JavaScript】理解与使用Javascript中的回调函数

    在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...

  9. Delphi回调函数及其使用

    Delphi回调函数及其使用 1 回调函数的概述 回调函数是这样一种机制:调用者在初始化一个对象(这里的对象是泛指,包括OOP中的对象.全局函数等)时,将一些参数传递给对象,同时将一个调用者可以访问的 ...

随机推荐

  1. Mvp快速搭建商城购物车模块

    代码地址如下:http://www.demodashi.com/demo/12834.html 前言: 说到MVP的时候其实大家都不陌生,但是涉及到实际项目中使用,还是有些无从下手.因此这里小编带着大 ...

  2. (三)Oracle学习笔记—— sql语句

    0. scott 用户默认表介绍 scott用户Tables目录下包含四张表 1. insert(插入)语句 给指定列插入数据: ,'xx'); 插入全部列数据: ,'xx','lll'); 2. u ...

  3. 灾备用Oracle语句备查

    Oracle常用Sql . 查看数据库的归档模式及闪回是否启用            select log_mode,open_mode,flashback_on .查看实例状态        sel ...

  4. php中的正则表达式

    一.定位字符 定位字符是正则表达式中又一类非常重要的字符,它的主要作用是用于对字符在匹配对象中的位置进行描述. ^:表示匹配的模式出现在匹配对象的开头(和在"[]"里面不同) $: ...

  5. Atitit.attilax的 case list 项目经验 案例列表

    Atitit.attilax的 case list 项目经验 案例列表 1. Atian inputmethod 输入法3 2. Ati desktop engine桌面引擎3 3. Acc资金账户系 ...

  6. UVA 11885 - Number of Battlefields(斐波那契)

    11885 - Number of Battlefields 题意:给周长.求能围成的战场数目.不包含矩形. 思路:详细的递推没递推出来,可是看了网上一个规律,假设包含矩形的答案应该是斐波那契数列(可 ...

  7. Unity3d中模型导入轴向不对的解决方法

    在unity3d中导入模型,经常会遇到模型的轴向与unity中默认的轴向不符合的情况. 网上有很多解决办法都是说在3dmax中导出模型时修改模型的轴向,那么我接下来讲的就是如何在unity里面修改模型 ...

  8. hdu5794 A Simple Chess 容斥+Lucas 从(1,1)开始出发,每一步从(x1,y1)到达(x2,y2)满足(x2−x1)^2+(y2−y1)^2=5, x2>x1,y2>y1; 其实就是走日字。而且是往(n,m)方向走的日字。还有r个障碍物,障碍物不可以到达。求(1,1)到(n,m)的路径条数。

    A Simple Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  9. python第四周迭代器生成器序列化面向过程递归

      第一节装饰器复习和知识储备------------ 第一节装饰器复习和知识储备------------ def wrapper(*args,**kwargs): index(*args,**kwa ...

  10. Redis的Aof被阻塞原因调查

    背景 Redis是单进程的,为了发挥多核的优势,我们redis集群采用在单台机器上部署多个redis实例,同时对持久化方式做了改进,采用rdb和增量的aof相结合的方式,appendfsync配置为n ...