如何封装C++的中的回调函数供C#调用
2个回答
展开全部
在c++中有个回调函数指针的概念,只需要某个函数在调用定时器函数时传入一个函数指针就能达到目的,但C#中没有函数指针的概念,我们该怎样来实现呢。
其实说到回调函数,大家应该能想到c#中的委托,虽然名字不一样,但在各自的语言范畴都能实现相似的功能。所以我们就可以大胆的尝试下,把c#中的委托传给c++,看c++是否能够承认它就是回调函数。
首先用c++写一个带有回调函数的方法 Test,在此省略。
接着,在c#中调用,如:
[DllImport("Test.dll",ChartSet.Ansi,EntryPoint="ReadMyVideo",ExactSpelling=false,CallingConvertion=CallingConvertion.StdCall)]
private static extern void Test(string fileName,CallbackDelegate callback);
接下来我们再定义一个委托:
public delegate void CallbackDelegate([marshalAs(UnmanagedType.LPArray,SizeConst=8010)]byte[] buffer,int count);
public static CallbackDelegate callback;
注:说明一下,在给c++传入数组参数时,必须得用[marshalAs(UnmanagedType.LPArray,SizeConst=8010)] 处理一下,相当于是告诉c++,c#传入的是一个长度为8010的数组类型,如果不写这句话的话,你回调函数接收到的参数将只有一条数据。
接下来看看怎样来调用:
在调用时,我们得先写一个接受c++传回参数的方法,即我们传入委托的实现方法。
private void CallBackFunction([marshalAs(UnmanagedType.LPArray,SizeConst=8010)]byte[] buffer,int count)
{
...//处理c++传过来的数据s
}
一切工作准备完毕之后,我们来进行最后一步操作把
public void GetData()
{
callback=CallBackFunction;
ReadMyVideo("",callback);
}
经过验证,委托就是c++要的回调函数。
其实说到回调函数,大家应该能想到c#中的委托,虽然名字不一样,但在各自的语言范畴都能实现相似的功能。所以我们就可以大胆的尝试下,把c#中的委托传给c++,看c++是否能够承认它就是回调函数。
首先用c++写一个带有回调函数的方法 Test,在此省略。
接着,在c#中调用,如:
[DllImport("Test.dll",ChartSet.Ansi,EntryPoint="ReadMyVideo",ExactSpelling=false,CallingConvertion=CallingConvertion.StdCall)]
private static extern void Test(string fileName,CallbackDelegate callback);
接下来我们再定义一个委托:
public delegate void CallbackDelegate([marshalAs(UnmanagedType.LPArray,SizeConst=8010)]byte[] buffer,int count);
public static CallbackDelegate callback;
注:说明一下,在给c++传入数组参数时,必须得用[marshalAs(UnmanagedType.LPArray,SizeConst=8010)] 处理一下,相当于是告诉c++,c#传入的是一个长度为8010的数组类型,如果不写这句话的话,你回调函数接收到的参数将只有一条数据。
接下来看看怎样来调用:
在调用时,我们得先写一个接受c++传回参数的方法,即我们传入委托的实现方法。
private void CallBackFunction([marshalAs(UnmanagedType.LPArray,SizeConst=8010)]byte[] buffer,int count)
{
...//处理c++传过来的数据s
}
一切工作准备完毕之后,我们来进行最后一步操作把
public void GetData()
{
callback=CallBackFunction;
ReadMyVideo("",callback);
}
经过验证,委托就是c++要的回调函数。
2015-01-01 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
向TA提问 私信TA
知道合伙人数码行家
采纳数:117538
获赞数:517196
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。
向TA提问 私信TA
关注
展开全部
要使用这样的回调需要:
1.继承这个接口类,重写OnRspError方法。
由于在C++/CLI中托管类不能继承非托管类,必须由一个非托管类(假设为CThostFtdcMdSpiImpl)继承CThostFtdcMdSpi。
2.注册回调时,传递一个CThostFtdcMdSpiImpl实例。
注意对象的生存期管理。
非托管类中不能储存托管句柄,但可以调用静态托管函数,或者使用Marshal类提供的GetFunctionPointerForDelegate获取并储存一个委托对应的函数指针。在OnRspError方法的实现中,你可以通过调用静态托管函数来间接引发托管事件,或者使用函数指针。
1.继承这个接口类,重写OnRspError方法。
由于在C++/CLI中托管类不能继承非托管类,必须由一个非托管类(假设为CThostFtdcMdSpiImpl)继承CThostFtdcMdSpi。
2.注册回调时,传递一个CThostFtdcMdSpiImpl实例。
注意对象的生存期管理。
非托管类中不能储存托管句柄,但可以调用静态托管函数,或者使用Marshal类提供的GetFunctionPointerForDelegate获取并储存一个委托对应的函数指针。在OnRspError方法的实现中,你可以通过调用静态托管函数来间接引发托管事件,或者使用函数指针。
本回答被提问者和网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询