как было сказано выше, для API функций, которые используют callback, обычно разрешается передать UserData (данные которые будут переданы программисту при вызове этой callback функции.
например есть такая API "условная" функция
- Код: Выделить всё
TCallbackProc = procedure (SomeData: Integer; UserData:Pointer); stdcall;
procedure SuperPupperAPIFunction( param1, param2: Integer; CallBackProc: TCallbackProc; UserData: Pointer); stdcall; external;
эта в эту функции, передаются входные параметры (param1, param2 - не важно что они значат - чисто условные). При работе этой функции будет вызываться CallBackProc, в который будет передана переменная UserData, та же сама, что и была передана при вызове SuperPupperAPIFunction.
как можно этим воспользоваться.
- Код: Выделить всё
type
TMyObject = class(Tobject)
procedure Callback(SomeData: Integer);
end;
// это обработчик
procedure TMyObject.CallBack(SomeData: Integer);
begin
writeln('SomeData = ', SomeData);
end;
procedure CallBackProc(SomeData: integer; UserData: Pointer); stdcall;
begin
// UserData это объект TMyObject, но нужно привести тип!
TMyObject(UserData).CallBack(SomeData); // передача из функции Callback методу объекта.
end;
...
var
m : TMyObject;
...
m := TMyObject.Create; // создали объект, иначе будет плохо!
...
SuperPupperAPIFunction( x, y, @CallBackProc, m); // в качестве UserData передали объект
...
end.
.хз как яснее написать... яснее будет на живом примере!
это использование типично для различный обёрток
и не только Delphi/FPC но и C++ и других объектно-оринетрованных языков, где в качестве UserData передаётся объект, и уже CallBack-процедура решает какой метод объекта нужно вызвать.
и ещё. Если писать класс обёртку, то следует "скрывать" (инкапсулировать - о как!) такое использование API, с помощью дополнительного метода объекта:
- Код: Выделить всё
interface
...
TMyObject = class(Tobject)
protected
procedure Callback(SomeData: Integer); virtual;
public
// обёртка вокруг API функции
procedure SuperPupper(param1, param2: Integer);
end;
...
implementation
procedure CallBackProc(SomeData: integer; UserData: Pointer); stdcall;
begin
// UserData это объект TMyObject, но нужно привести тип!
TMyObject(UserData).CallBack(SomeData); // передача из функции Callback методу объекта.
end;
// это обработчик
procedure TMyObject.CallBack(SomeData: Integer);
begin
writeln('SomeData = ', SomeData);
end;
// этот метод - обёртка для вызова функции SuperPupperAPIFunction
procedure TMyObject.SuperPupper(param1, param2: Integer);
begin
SuperPupperAPIFunction(param1, param2, @CallBackProc, Self);
end;
отличие этого когда, от перыдущего в том, что использование SuperPupperAPIFunction скрыто, что позволяет добится больше структурированности кода.
и ещё раз: "хз как яснее написать... яснее будет на живом примере"!
ЗЫ: искать хаки, для того чтобы передавать метод объекта, как процедуру - не стоит:
1-х эти решения не будут кроссплатформенными (увы и ах ВСЕГДА придёться лезть в ассемблер и основываться на convention call)
2-х они покажут, что ты программист-индус (в хучшем смысле этого слова).
3-х ненужное усложнение кода.