I'm writing a DLL wrapper to a C++Builder VCL class. This is an extremely simplified example of the problem:
typedef void __fastcall (__closure *TMyEvent)(int index);
class TMyClass {
public:
TMyEvent OnMyEvent;
};
void __fastcall myEventHandler(int index) { }
TMyClass myClass;
myClass.OnMyEvent = myEventHandler;
...and here is the problem:
Normally myEventHandler
is defined inside another class, but here it is defined as a global function. When I try to assign myEventHandler
to myClass.OnMyEvent
I get an error
Cannot convert void(int) to TMyEvent
I reuse the TMyClass
to generate different kind of wrappers and need the __closeure
in the typedef
so it works well with VCL form projects.
Is the __closure
the problem? Can I use a global function as an event handler at all?
The __closure
compiler extension is a special type of class method pointer that holds two pointers - a pointer to an object instance, and a pointer to the handler method. When the __closure
is executed, the compiler passes the object pointer to the handler via its this
parameter. As such, the handler MUST have a this
parameter.
If the handler is a non-static member of a class, the this
pointer is handled implicitly by the compiler for you, eg:
class TMyEvents {
public:
void __fastcall myEventHandler(int index) { }
};
TMyClass myClass;
TMyEvents myEvents;
myClass.OnMyEvent = myEvents.myEventHandler;
If the handler is a standalone function, or is a static method of a class, then the this
pointer must be provided in the parameter list explicitly. In this situation, you can use the TMethod
1 struct to help you assign the handler to the event, eg:
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: this only works with __closure
! Don't try to use it with other types of function pointers.