Советы по 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. [001196]



Содержание раздела