我正在设计一个使用用户代码提供的回调函数的C ++ / CLR类。
如果回调函数是空闲的(即不是类的成员),这非常有效。它与纯C ++几乎相同。
以下是一些效果良好的示例代码:
ref class ClassThatUsesCallback
{
public:
typedef void (*callback_t)( String^ );
void setCallback( callback_t pfun )
{
myCallback = pfun;
}
void Run()
{
if( myCallback != nullptr ) {
myCallback("This is a test");
}
}
private:
callback_t myCallback;
};
void FreeFunction( String^ s )
{
Console::WriteLine( "Free Function Callback " + s );
}
int main(array<System::String ^> ^args)
{
ClassThatUsesCallback^ theClassThatUsesCallback
= gcnew ClassThatUsesCallback();
theClassThatUsesCallback->setCallback( FreeFunction );
theClassThatUsesCallback->Run();
}
但是,我希望回调函数是用户代码中类的成员(因此它可以使用和更改用户代码类的属性)
以下代码无法编译
ref class ClassThatProvidesCallback
{
public:
void MemberFunction( String^ s )
{
Console::WriteLine( "Member Function Callback " + s );
}
void Run()
{
ClassThatUsesCallback^ theClassThatUsesCallback
= gcnew ClassThatUsesCallback();
theClassThatUsesCallback->setCallback(
&ClassThatProvidesCallback::MemberFunction );
theClassThatUsesCallback->Run();
}
};
我收到此错误
error C3374: can't take address of 'ClassThatProvidesCallback::MemberFunction'
unless creating delegate instance
当我研究这个时,我发现了很多关于如何从托管代码调用未托管代码的解释(反之亦然)我不需要这样做 - 所有涉及的代码都是管理的。所以我希望有人能指出我这个简单的方法。
答案 0 :(得分:1)
这是完整的解决方案:
ref class ClassThatUsesCallback
{
public:
void setCallback( Action<String^>^ callback )
{
myCallback = callback;
}
void Run()
{
if( myCallback != nullptr ) {
myCallback("This is a test");
}
}
private:
Action<String^>^ myCallback;
};
ref class ClassThatProvidesCallback
{
public:
void MemberFunction( String^ s )
{
Console::WriteLine( "Member Function Callback " + s );
}
void Run()
{
ClassThatUsesCallback^ theClassThatUsesCallback
= gcnew ClassThatUsesCallback();
theClassThatUsesCallback->setCallback(gcnew Action<String^>(this,
&ClassThatProvidesCallback::MemberFunction));
theClassThatUsesCallback->Run();
}
};
int main(array<System::String ^> ^args)
{
ClassThatProvidesCallback^ c = gcnew ClassThatProvidesCallback();
c->Run();
return 0;
}
本机C ++样式typedef
已替换为.NET Action
委托。附加参数this
被添加到setCallback
调用中,需要定义包含回调函数的类实例。