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我时出现错误

无法将 void(int) 转换为 TMyEvent

我重用TMyClass来生成不同类型的包装器并且需要__closeureintypedef以便它与 VCL 表单项目很好地配合。

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

4

1 回答 1

2

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

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

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

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

如果处理程序是独立函数,或者是类的静态方法,则this必须在参数列表中显式提供指针。在这种情况下,您可以使用1结构来帮助您将处理程序分配给事件,例如: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);

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

于 2017-05-09T20:34:20.973 回答