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中的对象.全局函数等)时,将一些参数传递给对象,同时将一个调用者可以访问的 ...
随机推荐
- tomcat 输入localhost:8080显示404 (找不到tomcat主页)
最近使用tomcat时常出现一个问题,tomcat开启后浏览器输入localhost:8080时显示404,但是输入项目的路径是可以看到效果的,因为没啥大碍,所以没有在意 [ 在这里顺便介绍几种访问 ...
- Flume、Kafka、Storm结合
Todo: 对Flume的sink进行重构,调用kafka的消费生产者(producer)发送消息; 在Sotrm的spout中继承IRichSpout接口,调用kafka的消息消费者(Consume ...
- 关于POI 中单元格背景色设置(转)
关于POI 中单元格背景色设置(转) csdn 中找到了用Apache POI 实现单元格背景色的小例子 我用了JDK6 + POI 3.17 ,调试中报错 最终将 CellStyle.SOLID ...
- ie6、ie7下JSON.parse JSON未定义的解决方法
解决方法一: var jsons = req.responseText; var s; if (typeof(JSON) == 'undefined'){ s = eval("(" ...
- mysql分组取最大(最小、最新、前N条)条记录
在数据库开发过程中,我们要为每种类型的数据取出前几条记录,或者是取最新.最小.最大等等,这个该如何实现呢,本文章向大家介绍如何实现mysql分组取最大(最小.最新.前N条)条记录.需要的可以参考一下. ...
- CQOI2016游记
前情提要:我是丝薄,noip405的丝薄,所以这次省选特别虚 day0 上午随便切了两个题.背了下版. 下午看考场,环境还好.键盘也不错.评測姬非常好,就是人和人之间有点近,我回去买了耳塞(尽管并没实 ...
- SGDMA-----Scatter-gather DMA
Scatter-gather DMA 使用一个链表描述物理上不连续的存储空间,然后把链表首地址告诉DMA master.DMA master在传输完一块物理连续的数据后,不用发起中断,而是根据链表来传 ...
- spring boot 打包报错
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.3.0.RELEASE:repac ...
- java的大端小端和c#如何对应
当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-en ...
- abp主机用户不过滤租户id
using (_unitOfWorkManager.Current.DisableFilter(DataFilterUtil.NowDisableFilter(AbpSession))) { var ...