C++Builder 控制台应用程序:链接到基于 __closure 的方法
C++Builder Console application: linking to a __closure based method
首先,请原谅我的标题。不太确定如何问这个问题:
我有一个应用程序需要转换为控制台应用程序(注意该应用程序作为 VCL 样式 windows 应用程序运行良好)。该应用程序使用一些具有回调函数的第 3 方小部件。但是,当我尝试编译它时,出现 'cannot convert ...' 错误,如下所示:
Cannot convert 'void(Tobject *, TErrorEventParams *)' to 'TErrorEvent'
TErrorEvent
定义为:
typedef void __fastcall (__closure* TErrorEvent)(System::TObject* Sender, TErrorEventParams *e);
导致错误的行是:
handler->OnError = errorHandler;
errorHandler 的代码是:
void __fastcall errorHandler(System::TObject* Sender, TErrorEventParams *e)
{
memoLine = e->Description;
updateLog();
}
查看此文档:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Closure
简而言之:
TErrorEvent
被定义为指向 class 成员函数的指针。所以 errorHandler
必须声明为 class 成员函数。
实现可能看起来像这样:
class TMyClass
{
private:
TMyHandler* handler;
void __fastcall errorHandler(System::TObject* Sender, TErrorEventParams *e);
public:
__fastcall TMyClass();
} my_dummy_class;
__fastcall TMyClass::MyClass()
{
//handler has to be created
handler->OnError = errorHandler;
}
void __fastcall TMyClass::errorHandler(System::TObject* Sender, TErrorEventParams *e)
{
memoLine = e->Description;
updateLog();
}
A __closure
类型是指向 non-static class 方法的指针。编译器不允许您在需要 __closure
的地方分配独立的 non-class 函数。它需要一个指向 class 对象方法的指针。 Karem 的回答向您展示了一种实现该目标的方法。
但是,是一种使用non-class函数的方法,使用助手TMethod
结构(__closure
在幕后实施)。
首先,向您的事件处理程序添加一个明确的 'this' 参数:
void __fastcall errorHandler(void *This, TObject* Sender, TErrorEventParams *e)
{
memoLine = e->Description;
updateLog();
}
然后像这样分配事件处理程序:
TMethod m;
m.Code = &errorHandler
m.Data = NULL; // any value you want to pass to the 'This' parameter...
handler->OnError = reinterpret_cast<TErrorEvent&>(m);
首先,请原谅我的标题。不太确定如何问这个问题:
我有一个应用程序需要转换为控制台应用程序(注意该应用程序作为 VCL 样式 windows 应用程序运行良好)。该应用程序使用一些具有回调函数的第 3 方小部件。但是,当我尝试编译它时,出现 'cannot convert ...' 错误,如下所示:
Cannot convert 'void(Tobject *, TErrorEventParams *)' to 'TErrorEvent'
TErrorEvent
定义为:
typedef void __fastcall (__closure* TErrorEvent)(System::TObject* Sender, TErrorEventParams *e);
导致错误的行是:
handler->OnError = errorHandler;
errorHandler 的代码是:
void __fastcall errorHandler(System::TObject* Sender, TErrorEventParams *e)
{
memoLine = e->Description;
updateLog();
}
查看此文档:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Closure
简而言之:
TErrorEvent
被定义为指向 class 成员函数的指针。所以 errorHandler
必须声明为 class 成员函数。
实现可能看起来像这样:
class TMyClass
{
private:
TMyHandler* handler;
void __fastcall errorHandler(System::TObject* Sender, TErrorEventParams *e);
public:
__fastcall TMyClass();
} my_dummy_class;
__fastcall TMyClass::MyClass()
{
//handler has to be created
handler->OnError = errorHandler;
}
void __fastcall TMyClass::errorHandler(System::TObject* Sender, TErrorEventParams *e)
{
memoLine = e->Description;
updateLog();
}
A __closure
类型是指向 non-static class 方法的指针。编译器不允许您在需要 __closure
的地方分配独立的 non-class 函数。它需要一个指向 class 对象方法的指针。 Karem 的回答向您展示了一种实现该目标的方法。
但是,是一种使用non-class函数的方法,使用助手TMethod
结构(__closure
在幕后实施)。
首先,向您的事件处理程序添加一个明确的 'this' 参数:
void __fastcall errorHandler(void *This, TObject* Sender, TErrorEventParams *e)
{
memoLine = e->Description;
updateLog();
}
然后像这样分配事件处理程序:
TMethod m;
m.Code = &errorHandler
m.Data = NULL; // any value you want to pass to the 'This' parameter...
handler->OnError = reinterpret_cast<TErrorEvent&>(m);