CLR/C++回调函数callback和C# delegate的互相转换

发布时间 2023-12-25 15:24:55作者: fanly_sus

在进行CLR/C++进行开发的时候会经常遇到C++回调函数和C#的delegate之间的相互转换,例如在C++非托管类型的代码中的回调函数需要使用C#类的函数,或者是在C#代码中需要使用非托管C++的函数,这时候就需要在回调函数和delegate代理之间进行转换。

C++:
回调函数:
typedef void (*pfunc)(int);

调用函数:
void setCallback(pfunc func)
{
func(100);
}

C#:

public delegate void Handler(int);

ref class HandlerClass
{
public:
void HandlerFunc1(int v)
{
Console::WriteLine("class func:{0}",v);
}

static void HandlerFunc2(int v)
{
    Console::WriteLine("class static func:{0}", v);
}

};

场景一:
setCallBack()使用C#的类函数:
Handler^ pHandler1 = gcnew Handler(&HandlerClass::HandlerFunc2);//静态函数方法

HandlerClass^ op = gcnew HandlerClass;
Handler^ pHandler2 = gcnew Handler(op, &HandlerClass::HandlerFunc1);//类成员函数

//从托管代码获取函数回调
IntPtr pter= Marshal::GetFunctionPointerForDelegate(pHandler1);
//转换为函数回调
pfunc ipc = static_cast(pter.ToPointer());
//应用回调
setCallback(ipc);

场景二:
//从非托管C++ 函数ipc转换为IntPtr
IntPtr pmter = static_cast(ipc);
//从IntPtr获取C#的delegate代理
auto del= Marshal::GetDelegateForFunctionPointer(pmter, pHandler1->GetType());
//将代理转换为目标的delegate代理
Handler^ mdel = static_cast<Handler^>(del);
//调用代理delegate
if (mdel)
{
mdel(2300);
}

转自https://www.bilibili.com/read/cv24345788/