Используйте неклассный член в качестве обработчика события
Я пишу оболочку DLL для класса C++Builder VCL. Это чрезвычайно упрощенный пример проблемы:
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 ответ
__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
! Не пытайтесь использовать его с другими типами указателей на функции.