![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
method pointer ВМЕСТО regular procedure?
Timego © (2004-10-07 15:48:00)Есть некая функция, которая в качестве параметра требует указатель на коллбэк функцию.
procedure CreateSmth(ACallBack: PCallBack),
где
PCALLBACK = procedure(...) stdcall;
Возникла огромная необходимость передать в CreateSmth метод класса вместо ссылки на глобальную процедуру типа PCallBack.
Компилятор, конечно, не дал этого сделать, резонно указав, что "Incompatible types: method pointer and regular procedure". Это я и без него знал, но где-то настраницах FAQ или этого форума я видел подсказку о хитром (или не очень) способе обойти это недрозумение и все-таки передавать в CreateSmth метод класса.
Буду благодаен за помощь!
the (2004-10-07 17:58:00) [1]>DiamondShark © (07.10.04 16:37) [8]
В случае, когда помимо ф-и передётся ещё и пользовательский
указатель, который идет первымаргументом колбэк ф-и, можно вообще не использовать заглушки, а сразу использовать прямо метод как указатель на простую ф-ю (TMethod.Code)
TTest = class
procedure CallBack( (* Contex = Self *) ...); stdcall;
// сам по себе медод - это по сути процедура с дополнительным
// аргументом Self.
end;
TCallBackMeth = procedure (...)of object; stdcall;
TCallBackProc = procedure (Context: Pointer; ...); stdcall;
m: TCallBackMeth;
test: TTest;
...
m := test.CallBack;
CreateSmth(TCallBackProc(TMethod(m).Code), TMethod(m).Data);
//CreateSmth(TCallBackProc(@TTest.CallBack), Pointer(test));
// Но в ф-и, которой передаётся колбэк ф-я, должен одновременно
// передаваться и пользовательский указатель.
// если это не так, то поможет только аналог
// MakeObjectInstance
Суслик (2004-10-07 16:39:00) [2]
> [8] DiamondShark © (07.10.04 16:37)
давай спорить не будем - ясно что методов до фига и больше.
DiamondShark (2004-10-07 16:37:00) [3]
> тогда надо знать какой метод. у?
Кю.
А методов сотня что-ли?
А хоть бы и сотня. На каждый метод -- заглушка вида:
procedure CallBackA(Context: Pointer; ...);
begin
TMyClass(Context).MethodA(...)
end;
procedure CallBackB(Context: Pointer; ...);
begin
TMyClass(Context).MethodB(...)
end;
> вооще судя по описанию callback параметр acontext скорее
> делает именно то, о чем я говорю.
Ну дык. Полагаться на телепатические способности становится уже доброй практикой ;)
Суслик (2004-10-07 16:25:00) [4]вооще судя по описанию callback параметр acontext скорее делает именно то, о чем я говорю.
Суслик (2004-10-07 16:24:00) [5]тогда надо знать какой метод. у?
DiamondShark (2004-10-07 16:23:00) [6]
> В этих 4х байтах можно передать адрес записи, содержащей
> метод переданный в CreateSmth
В этих 4х байтах можно передать указатель на экземпляр, чей метод надо вызвать. Ы?
Суслик (2004-10-07 16:12:00) [7]Есть еще вариант.
Многие фукнции кроме callback повзволяют еще передать 4 байта, которые фукнция переправит в callback. В этих 4х байтах можно передать адрес записи, содержащей метод переданный в CreateSmth. В callback вывывать этот метод. Это позволит обойтись без глобальных переменных.
Суслик (2004-10-07 16:04:00) [8]1. просто так сделать и передать метод вместо процедуры нельзя, т.к. процедурный тип есть 4 байта (pointer), а тип-метод - 8 байт (адрес объекта и метода в нем).
2. Если тебе нужно передавать в CreateSmth метод, то и передавай метод.
3. Насколько я понимаю, дальше тебе необходимо передать этот метод в некую функцию (предполагаю, что НЕ твоей разработки).
4. Нет ничего проще. Описываешь callback как раньше (т.е. глобальную процедуру). Описываешь глоб. перем. в которую в методе CreateSmth запсываешь переданный ей метод. В callback пишешь вызов метода из глобальной переменной.
т.е. примерно так.
TMet = procedure of object;
var
M: TMet;
procedure Callback(
const ANUMBER : CNUMBER;
AContext, ASpecial1, ASpecial2 : Pointer) stdcall;
begin
M();
end;
procedure CreateSmth(aM: TMet);
begin
M := aM;
FuntThatNeedsCallback(Callback);
end;
Timego (2004-10-07 15:58:00) [9]
> Это не оконная процедура случаем?
Нет, это не оконная процедура ни в коем случае. Описана так:
PCALLBACK = procedure(
const ANUMBER : CNUMBER;
AContext, ASpecial1, ASpecial2 : Pointer) stdcall;
где
CNUMBER =
(
CN_ADD,
CN_REMOVE, ...
Суслик (2004-10-07 15:50:00) [10]Давай сначала определимся с тем, как описан callback?
приведи описание?
Это не оконная процедура случаем?