使用非类成员作为事件处理程序

时间:2017-05-09 13:00:10

标签: eventhandler c++builder-10.1-berlin

我正在为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吗?我可以使用全局函数作为事件处理程序吗?

1 个答案:

答案 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!不要试图将它与其他类型的函数指针一起使用。