C++调用C# 需要三步:1、定义函数指针 2、C#委托转换成函数指针 3、C#层指定要回调的委托
注意事项:委托对象一定要是持久型对象,不然委托对象被C#回收后,C++再调用委托对象会出现崩溃。
1、定义函数指针
typedef void(CALLBACK* pEventCallBack)(int nEvent);
定义函数指针对象
class testCpp
{
public:
void RegisterEventCallBk(pEventCallBack inCallBk);
private:
pEventCallBack mEventCallback;//事件回调函数
}
//指定回调函数
void testCpp::RegisterEventCallBk(pEventCallBack inCallBk)
{
mEventCallback = inCallBk;
}
2、托管封装CLR
//头文件 MotionVision_CS.h
namespace YC3000MotionAssmbly
{
public delegate void EventCallBkNET(int innEvent);
class MotionVision_CS
{
public:
static void CS_SetEventCallbk(EventCallBkNET^ inCallBk);
}
}
//cpp文件 MotionVision_CS.cpp
#include "stdafx.h"
#include "MotionVision_CS.h"
#include <msclr\marshal.h>
#include <msclr/marshal_windows.h>
#include <msclr/marshal_cppstd.h>
using namespace msclr::interop;
using namespace System::Runtime::InteropServices;
testCpp myTestCpp;
void YC3000MotionAssmbly::MotionVision_CS::CS_SetEventCallbk(EventCallBkNET^ inCallBk)
{
IntPtr c_cbDownloadCallback = Marshal::GetFunctionPointerForDelegate(inCallBk);//可将pvFun强制转化为void*,再强制转化为FUN类型
myTestCpp.RegisterEventCallBk(reinterpret_cast<pEventCallBack>(c_cbDownloadCallback.ToInt32()));
}
3、C#层指定回调函数
//Wpf 窗体的CS文件
EventCallBkNET mCallBk;
//回调的执行函数
void CallBkfun(int i)
{
System.Diagnostics.Debug.WriteLine("收到-" + i.ToString());
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
mCallBk = new EventCallBkNET(CallBkfun);//定义委托对象
MotionVision_CS.CS_SetEventCallbk(mCallBk);//指定回调
}