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

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

процедурные типы [D5, WinME]


einsam ©   (2002-08-15 00:56:00) 

Здравствуйте.
Следующий код является ошибочным:
type
TMyProc: procedure (Param: integer);
PMyProc: ^TMyProc;
...
begin
...
PointToProc := @SomeProc;
PointToProc^(1);
...
end;

Ошибка возникает при разыменовывании указателя - неверный
доступ к памяти. А вот почему такое действие нельзя произвести?


einsam   (2002-08-15 02:29:00) [1]

А вот за это большое спасибо вам.


Юрий Зотов   (2002-08-15 02:04:00) [2]

Почему бы и нет?

Мы же получаем nil, когда GetProcAddress не находит функцию в DLL - и никаких проблем. Но проверять надо с @:

if @Proc <> nil then Proc(...)

Можно даже сделать этот параметр необязательным:

procedure MyEnumProc(..., CallbackProc: TProc = nil);
begin
if @CallbackProc <> nil then CallbackProc(...)
end;


einsam   (2002-08-15 01:56:00) [3]

>Юрий Зотов © (15.08.02 01:38)
Здесь я код несколько упростил. В действительности же ситуация несколько иная. Моя процедура получает данный указатель в качестве параметра. Далее происходит этакий Callback-вызов. Можно, конечно, сделать этот параметр обычного процедурного типа (как предлагаете Вы), но хотелось бы учесть ситуацию, когда в параметр процедуру передавать не надо, и вместо нее передается nil. Посему и решил пойти через указатели.
Стоп. А может быть можно спокойно передать nil и при использовании обычного процедурного типа? Вы это имеете ввиду?


Юрий Зотов   (2002-08-15 01:38:00) [4]

Произвести можно, но немного иначе.

Процедуры и функции - сами по себе уже указатели. Компилятор трактует @SomeProc и SomeProc как один и тот же адрес, а операция @ здесь нужна лишь для обхода синтаксической неоднозначности - чтобы в неявных случаях подчеркнуть, что надо не вызвать процедуру, а взять ее адрес.

procedure Proc(Param: integer);
begin
ShowMessage(IntToStr(Param))
end;

type
TProc = procedure(Param: integer);

procedure TForm1.Button1Click(Sender: TObject);
var
P: TProc; // а не ^TProc
begin
P := @Proc; // можно и без @
P(1) // без всяких разыменований
end;


Наверх

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