我正在为C ++ Builder VCL类编写DLL包装器。这是一个极其简化的问题示例:
typedef void __fastcall (__closure *TMyEvent)(int index);
class TMyClass {
public:
TMyEvent OnMyEvent;
};
void __fastcall myEventHandler(int index) { }
TMyClass myClass;
myClass.OnMyEvent = myEventHandler;
......这就是问题所在:
通常myEventHandler
在另一个类中定义,但在此定义为全局函数。当我尝试将myEventHandler
分配给myClass.OnMyEvent
时,我收到错误
无法将void(int)转换为TMyEvent
我重复使用TMyClass
来生成不同类型的包装器,并且需要__closeure
中的typedef
,因此它适用于VCL表单项目。
问题是__closure
吗?我可以使用全局函数作为事件处理程序吗?
答案 0 :(得分:2)
__closure
编译器扩展是一种特殊类型的类方法指针,它包含两个指针 - 指向对象实例的指针和指向处理程序方法的指针。执行__closure
时,编译器通过其this
参数将对象指针传递给处理程序。因此,处理程序必须具有this
参数。
如果处理程序是类的非静态成员,编译器会为您隐式处理this
指针,例如:
class TMyEvents {
public:
void __fastcall myEventHandler(int index) { }
};
TMyClass myClass;
TMyEvents myEvents;
myClass.OnMyEvent = myEvents.myEventHandler;
如果处理程序是独立函数,或者是类的静态方法,则必须在参数列表中明确提供this
指针。在这种情况下,您可以使用TMethod
1 结构来帮助您为事件分配处理程序,例如:
void __fastcall myEventHandler(void *Data, int index) { }
TMethod m;
m.Data = ...; // can be anything you want to pass to the 'Data' parameter
m.Code = &myEventHandler;
TMyClass myClass;
myClass.OnMyEvent = reinterpret_cast<TMyEvent&>(m);
1 :这只适用于__closure
!不要试图将它与其他类型的函数指针一起使用。