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

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

Процедурные указатели.. [D5, 2000]


pathfinder ©   (2006-11-19 11:08:00) 

Добрый день!
Помогите, пожалуйста, разобраться в следующем:

type
 THtmlHelp = function(hwndCaller : THandle; pszFile : PChar; uCommand : cardinal; dwData : longint) : integer; stdcall;

var
 HtmlHelpProc : THtmlHelp;
 HHCtrlHandle : THandle;
...
//загружаю библиотеку
HHCtrlHandle := LoadLibrary('HHCtrl.ocx');
//импортирую оттуда функцию
if (HHCtrlHandle <> 0) then
 @HtmlHelpProc := GetProcAddress(HHCtrlHandle, 'HtmlHelpA');  

как я понимаю здесь происходит присвоение адреса ф-ции HtmlHelpA процедурному указателю HtmlHelpProc..а что произойдет, если убрать @ перед HtmlHelpProc? Работает вроде также..


palva   (2006-11-20 11:21:00) [1]


{$APPTYPE CONSOLE}
//  {$T+}
type
 Tf = function: Integer;
function f:Integer;
begin
 Result := 6;
end;
var
 f1, f2: Tf;
 n: Integer;
begin
 // f - вызов функции
 // @f - адрес точки входа
 // f1 занимает 4 байта и хранит адрес точки входа
 // f1 используется как вызов функции
 // @f1 содержимое переменной f1 - адрес входа функции тип Pointer
 // @@f1 адрес переменной f1
 @f1 := @f;
 @f2 := @f1;
 n := f1;              // Здесь вызов функции
 WriteLn(n);           // 6
 n := Integer(@f1);    // Здесь адрес точки входа
 WriteLn(n);           // 4209892
 n := Integer(@f2);    // Здесь та же точка входа
 WriteLn(n);           // 4209892
 n := Integer(@@f1);   // Здесь адрес переменной f1
 WriteLn(n);           // 4216412
 n := Integer(@@f2);   // Адрес другой переменной f2
 WriteLn(n);           // 4216416
 @f1 := @f;            // Корректная форма оператора
 f1 := f;              // Это тоже правильно работает.
 f1 := @f;             // А это не компилируется, если стоит режим {$T+}
                       // сообщение: Incompatible types 'Tf' and 'Pointer'
end.


pathfinder   (2006-11-20 11:12:00) [2]

понятно..всем спасибо!


clickmaker   (2006-11-20 10:27:00) [3]


> [6] pathfinder ©   (20.11.06 09:52)

ну добавили интеллектуальности компилятору. Он по контексту определяет, что ты от него хочешь собственно, а код-то генерит в любом случае один и тот же.
Лично я всегда пишу с @. Для единообразия и чтоб неоднозначности не было


pathfinder   (2006-11-20 09:52:00) [4]


> palva ©   (19.11.06 20:21) [4]

я тоже не препод) просто хочется понять суть..то что работает конечно хорошо, но мне как-то не по себе когда я пишу код и не до конца понимаю что он делает..


jack128   (2006-11-19 22:40:00) [5]

pathfinder ©   (19.11.06 19:21) [3]
или в данном случае они равноценны?

в данном случае - да


palva   (2006-11-19 20:21:00) [6]

Что-то я здесь уже запутался. По-моему, начиная с некоторой версии здесь сделали очень свободный синтаксис, зависящий к тому же от контекста. Я такими вопросами стараюсь не задаваться. Работает код - и ладно. С другой стороны, если ты препод, а студент задает вопрос? Я слава богу не препод.


pathfinder   (2006-11-19 19:21:00) [7]

..просто хотелось бы понять чем по существу отличается запись
@HtmlHelpProc := GetProcAddress(HHCtrlHandle, 'HtmlHelpA'); от
HtmlHelpProc := GetProcAddress(HHCtrlHandle, 'HtmlHelpA');  
или в данном случае они равноценны?


palva   (2006-11-19 11:37:00) [8]

Насколько я понимаю, у функции нет адреса, у нее есть точка входа. Поэтому договорились, что если к имени функции применить @ то получим адрес точки входа. Если переменная имеет функциональный тип и содержит точку входа функции, то имя этой переменной можно использовать точно также как имя фукнции. Поэтому логично выглядит, когда оператор @, примененный, к такой переменной дает не адрес этой переменной, а снова точку входа этой функции. Если же вам нужен адрес этой переменной, то применяйте @@.
Вот я попробовал такой пример на Turbo Delphi.

{$APPTYPE CONSOLE}
type
 Tf = function(i: Integer): Integer;
 Pf = ^Tf;
var
 f1, f2: Tf;
 p: Pf;
function f(i: Integer): Integer;
begin
 f := 555 + i;
end;

begin
 f1 := f;
 f2 := f1;
 p := @@f2;
 WriteLn(p^(1)); // 556
 Readln;
end.


jack128   (2006-11-19 11:35:00) [9]

pathfinder ©   (19.11.06 11:08)
Работает вроде также..

работает. В некоторых случаях @ перед названием переменной процедурного типа писать не нужно...


Наверх

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