Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.10.24;
Скачать: [xml.tar.bz2];

Вниз

method pointer ВМЕСТО regular procedure?   Найти похожие ветки 

 
Timego   (2004-10-07 15:48) [0]

Есть некая функция, которая в качестве параметра требует указатель на коллбэк функцию.

procedure CreateSmth(ACallBack: PCallBack),
где
PCALLBACK = procedure(...) stdcall;

Возникла огромная необходимость передать в CreateSmth метод класса вместо ссылки на глобальную процедуру типа PCallBack.

Компилятор, конечно, не дал этого сделать, резонно указав, что "Incompatible types: method pointer and regular procedure". Это я и без него знал, но где-то настраницах FAQ или этого форума я видел подсказку о хитром (или не очень) способе обойти это недрозумение и все-таки передавать в CreateSmth метод класса.

Буду благодаен за помощь!


 
Суслик ©   (2004-10-07 15:50) [1]

Давай сначала определимся с тем, как описан callback?

приведи описание?

Это не оконная процедура случаем?


 
Timego   (2004-10-07 15:58) [2]


> Это не оконная процедура случаем?


Нет, это не оконная процедура ни в коем случае. Описана так:

 PCALLBACK = procedure(
   const ANUMBER : CNUMBER;
   AContext, ASpecial1, ASpecial2 : Pointer) stdcall;

где

 CNUMBER =
 (
   CN_ADD,
   CN_REMOVE, ...


 
Суслик ©   (2004-10-07 16:04) [3]

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;


 
Суслик ©   (2004-10-07 16:12) [4]

Есть еще вариант.
Многие фукнции кроме callback повзволяют еще передать 4 байта, которые фукнция переправит в callback. В этих 4х байтах можно передать адрес записи, содержащей метод переданный в CreateSmth. В callback вывывать этот метод. Это позволит обойтись без глобальных переменных.


 
DiamondShark ©   (2004-10-07 16:23) [5]


> В этих 4х байтах можно передать адрес записи, содержащей
> метод переданный в CreateSmth

В этих 4х байтах можно передать указатель на экземпляр, чей метод надо вызвать. Ы?


 
Суслик ©   (2004-10-07 16:24) [6]

тогда надо знать какой метод. у?


 
Суслик ©   (2004-10-07 16:25) [7]

вооще судя по описанию callback параметр acontext скорее делает именно то, о чем я говорю.


 
DiamondShark ©   (2004-10-07 16:37) [8]


> тогда надо знать какой метод. у?

Кю.
А методов сотня что-ли?
А хоть бы и сотня. На каждый метод -- заглушка вида:

procedure CallBackA(Context: Pointer; ...);
begin
 TMyClass(Context).MethodA(...)
end;
procedure CallBackB(Context: Pointer; ...);
begin
 TMyClass(Context).MethodB(...)
end;


> вооще судя по описанию callback параметр acontext скорее
> делает именно то, о чем я говорю.

Ну дык. Полагаться на телепатические способности становится уже доброй практикой ;)


 
Суслик ©   (2004-10-07 16:39) [9]


>  [8] DiamondShark ©   (07.10.04 16:37)

давай спорить не будем - ясно что методов до фига и больше.


 
the   (2004-10-07 17:58) [10]

>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



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.10.24;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.053 c
4-1095706253
Игорь_
2004-09-20 22:50
2004.10.24
как программно изменить StaticText на чужой форме?


3-1096019705
janb
2004-09-24 13:55
2004.10.24
Уважаемые мастера!!! Как в fastreporte создать компоненты?


14-1096813014
Yuri Btr
2004-10-03 18:16
2004.10.24
Потоковый звук


6-1092483093
MC
2004-08-14 15:31
2004.10.24
разработка протокола


3-1095744487
Fishka
2004-09-21 09:28
2004.10.24
Level DBF-файлов 5 и 7 - какое это имеет значение?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский