2017-05-09 38 views
0

我正在写一个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是另一个类中定义的,但在这里它被定义为一个全球性的功能。当我尝试分配myEventHandlermyClass.OnMyEvent我得到“无法转换无效(int)以TMyEvent”

我重用TMyClass产生不同类型的包装,并需要在typedef__closeure所以它与VCL形式的项目运作良好。

这是问题(__closure)?我可以使用全局函数作为事件处理程序吗?

回答

2

__closure编译器扩展是一种特殊类型的方法指针,它持有两个指针 - 一个指向对象实例的指针和一个指向处理函数方法的指针。当执行__closure时,编译器通过参数this将对象指针传递给处理函数。因此,处理程序必须有一个this参数。

如果处理程序是一类的非静态成员,this指针隐式由编译器为您处理,如:

class TMyEvents { 
public: 
    void __fastcall myEventHandler(int index) { } 
}; 

TMyClass myClass; 
TMyEvents myEvents; 
myClass.OnMyEvent = myEvents.myEventHandler; 

如果处理程序是一个独立的函数,或者是一个静态方法,那么必须显式地在参数列表中提供this指针。在这种情况下,你可以使用TMethod 结构来帮助你分配处理程序的事件,如:

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); 

:这仅适用于__closure!不要试图将其与其他类型的函数指针一起使用。

+0

我会尽快找回来...... –

相关问题