Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

Курс видеоуроков программирования и крэкерства 5.0
(актуальность: январь 2017)
Свежие инструменты, новые видеоуроки!

  • 300+ видеоуроков
  • 800 инструментов
  • 80 свежих книг и статей

УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

БОЛЬШОЙ FAQ ПО DELPHI



Передача функции как параметра

В нашем случае лучшим решением будет использование процедурного типа. Допустим, что DllFunction() на входе хочет получить определенную функцию, поясним это на примере кода:


 type
   TMyFuncType = function: integer;
 
 var
   MyFunc: TMyFuncType;
 
 function foo: integer;
 begin
   result := 1;
 end;
 
 begin
   MyFunc := foo;
   DllFunction(longint(MyFunc));
 

Вы можете это сделать и так:


 DllFunction( longint( @foo )) ;
 

Все же я не уверен в вопросах корректности использования таким образом в вызовах DLL. памяти (для меня пока неясна работа с памятью, находящейся в другом сегменте), как в этом примере, так что возможно для корректной работы вам придется объявить foo с директивой far, экспортировать ее в модуле, или что-то еще.

Также, в зависимости от того, как написана DllFunction(), вы можете в вызове подразумевать приведение типа:


 function DllFunction( p: TMyFuncType ): Integer;
 far; external 'mydll';
 

В этом случае вам не нужна будет переменная MyFunc или оператор @.

В Delphi/Pascal вы можете передавать функции как параметры. Тем не менее, чтобы этим воспользоваться, необходимо для компилятора установить тип. Попробуйте следующий код (я реально его компилил и тестировал):


 unit Unit1;
 
 interface
 
 uses
 
   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
   Forms, Dialogs, StdCtrls;
 
 type
 
   TForm1 = class(TForm)
     Button1: TButton;
     Button2: TButton;
     procedure Button1Click(Sender: TObject);
     procedure Button2Click(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end;
 
 var
 
   Form1: TForm1;
 
 implementation
 
 {$R *.DFM}
 
 type
 
   IntFunc = function: integer;
 
 function DllFunction(iFunc: IntFunc): integer; far;
 begin
 
   DllFunction := iFunc; {Обратите внимание на то, что это вызов функции}
 end;
 
 function iFoo: integer; far;
 begin
 
   iFoo := 1;
 end;
 
 procedure TestIFunc;
 var
 
   i: integer;
 begin
 
   i := DllFunction(iFoo);
 end;
 
 procedure TForm1.Button1Click(Sender: TObject);
 begin
 
   TestIFunc;
 end;
 
 procedure TForm1.Button2Click(Sender: TObject);
 begin
 
   Close;
 end;
 
 end.
 

Вы можете сделать две вещи. Во-первых, если вы хотите использовать для передачи longint, напишите следующий код:


 i := longint(@foo)
 

Другая вещь, которую вы можете сделать - исключить работу с longint и вызывать функцию dll следующим образом:


 DLLfunction (@foo);
 

Имейте в виду, что если вы собираетесь вызывать foo из DLL, то необходимо предусмотреть вопросы совместимости, для получения дополнительной информации почитайте описание функции MakeProcInstance.




<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS