Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Методы и процедуры [D7, WinXP]


Страницы:   1 2 3

Doma ©   (2006-09-15 18:48:00) 

Всем привет!
Помогите разобраться.

Есть два типа:

TMyProc1 = procedure(a,b: integer);
TMyProc2 = procedure(a,b: integer) of object);
PMyProc1 = ^TMyProc1
PMyProc2 = ^TMyProc2;

И есть процедура, который выполняет процедуры типа TMyProc1

procedure ExecProc1(proc: PMyProc1; a,b: integer);
var p: TMyProc1;
begin
 @p := proc;
 p(a,b);
end;

Задача сделать так чтобы эта же процедура могла выполнчть и методы типа TMyProc2.


isasa   (2006-09-16 12:26:00) [1]

begin...end ©   (16.09.06 12:12) [52]
Я когдато на stdcall науродовался, пока не вырыл это в хелпе. После этого, даже сохранил этот текст отдельно в файл. :)

По сабжу. А кто мешает сделать так

TMyProc1 = procedure(self: pointer; a,b: integer); stdcall;
TMyProc2 = procedure(a,b: integer) of object; stdcall;

и вызывать не разбираясь?

stdcall - для Plug in, очень даже нормально.


begin...end   (2006-09-16 12:12:00) [2]

> isasa ©   (16.09.06 11:44) [51]

Угу, насчёт pascal -- не знал.


isasa   (2006-09-16 11:44:00) [3]

Не все так просто.
Вот выдержка из глубин желпа.

Methods use the same calling conventions as ordinary procedures and functions,
except that every method has an additional implicit parameter Self,
which is a reference to the instance or class in which the method is called.
The Self parameter is passed as a 32-bit pointer.

Under the register convention, Self behaves as if it were declared before all other parameters.
It is therefore always passed in the EAX register.

Under the pascal convention,
Self behaves as if it were declared after all other parameters
(including the additional var parameter sometimes passed for a function result).
It is therefore pushed last, ending up at a lower address than all other parameters.

Under the cdecl, stdcall, and safecall conventions,
Self behaves as if it were declared before all other parameters, but after the additional
var parameter (if any) passed for a function result.
It is therefore the last to be pushed, except for the additional var parameter.


begin...end   (2006-09-16 07:53:00) [4]

> Palladin ©   (15.09.06 21:11) [35]

При любом соглашении о вызове метода Self передаётся как первыйнеявный его параметр. Я полагал, что речь идёт именно об этом (см. [24]: "передается, в параметрах самым первым").


oxffff   (2006-09-16 02:59:00) [5]

to eraser
>и к чему эта куча сообщений? ) думаешь кому-то здесь открыл на что-то >глаза :)

Абсолютно нет.

to zamtmn
А что касаемо оbject. Согласен

Безуслосно нужно использовать первый способ


zamtmn   (2006-09-16 00:19:00) [6]

первое конечно не к Eraser, а к oxffff, сорри:)


zamtmn   (2006-09-16 00:18:00) [7]

>Eraser
TMyProc2 = procedure(a,b: integer) of object
вовсе не подразумевает метод class`а, это может быть метод objecta`а, такчто третий способ не катит:)
>Doma
к чему PMyProc1 = ^TMyProc1?
TMyProc1 сам по себе является указателем
Лучше пересмотри свою систему плагинов, или пиши 2 разных процедуры для вызова процедур и методов.
PMyProc1 у тебя ^pointer
PMyProc2 у тебя ^Tmethod
и по proc: PMyProc1, ты никак не что нужно вызвать, никакие is и try не помогут


Eraser   (2006-09-15 23:18:00) [8]

> oxffff ©

и к чему эта куча сообщений? ) думаешь кому-то здесь открыл на что-то глаза :)


oxffff   (2006-09-15 23:08:00) [9]

Хотя подождите.
Только не смейтесь.

var a:Tmethod;
begin
.........
ExecProc1(@a,1,2);

и далее применяем oxffff ©   (15.09.06 22:51) [43]


oxffff   (2006-09-15 22:54:00) [10]

Тут с третьим способом я поторопился. :)
Извиниюсь


oxffff   (2006-09-15 22:51:00) [11]

Третий способ Костыльный способ

В процедуре ExecProc1 проверять EAX и таблицу VTB.
Естественно загородить все в try except.
Далее
-44 Pointer pointer to short string containing class name
Сравнить с Tobject.
Если нет далее VBT родителя и т.д. До исключения, либо до Tobject


oxffff   (2006-09-15 22:33:00) [12]

Второй вариант

procedure ExecProc1(proc: PMyProc1; a,b: integer);
var p: TMyProc1;
begin
@p := proc;
p(a,b);
end;

Procedure Abc(a,b:integer);
begin

end;

procedure MethodSmart(a,b:integer);
begin
globalVariableMethod(a,b);
end;

Думаю можно еще улучшить


oxffff   (2006-09-15 22:20:00) [13]

Паттерны друзья. Паттерны.
Гамма, Хелм, Джонсон, Влиссидес


oxffff   (2006-09-15 22:19:00) [14]

>Задача написать процедуру, которая могла бы выполнять и методы и процедуры!! Куда конкретней!

Так сделай абстрактный класс.
Один потомок вызывает методы, второй процедуры.

procedure ExecProc(prcObject: AbstractCallerClass; a,b: integer);
begin
prcObject.call(a,b);
end;

Можно конечно и так выкрутиться но сложнее.


guav   (2006-09-15 22:16:00) [15]

> [38] oxffff ©   (15.09.06 22:11)

Речь шла именно о self, так что он всегда попадает в регистр. Ошибся я как раз с остальными соглашениями вызова (верх стека - это большие адреса, потому верх/низ в [36]  наоборот).


oxffff   (2006-09-15 22:11:00) [16]

To  guav
>Если смотреть на место в списке параметров - не зависит.
>Если смотреть на расположение в стеке - разумеется, зависит - при >stdcall/cdecl/safecall он наверху, при pascal внизу, при register вообще не >попадает в стек.

Слегка поправлю про register

The register convention uses up to three CPU registers to pass parameters, while the other conventions pass all parameters on the stack.


Palladin   (2006-09-15 21:54:00) [17]


> Если смотреть на расположение в стеке

о чем и речь...


guav   (2006-09-15 21:53:00) [18]

Если смотреть на место в списке параметров - не зависит.
Если смотреть на расположение в стеке - разумеется, зависит - при stdcall/cdecl/safecall он наверху, при pascal внизу, при register вообще не попадает в стек.


Palladin   (2006-09-15 21:11:00) [19]


> [34] begin...end ©

Зависит.


begin...end   (2006-09-15 20:22:00) [20]

> Lamer@fools.ua ©   (15.09.06 20:11) [27]
> Зависит от соглашения о вызовах.

Насколько я знаю, не зависит.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо