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

В этом случае лучшим решением будет использование процедурного типа. Допустим, что 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
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  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.
Возможны два способа. Первый заключается в использовании следующего кода:

i := longint(@foo);
Такой способ подойдет, если вы хотите применить для передачи longint. Другой вариант, которым можно воспользоваться – исключить работу с longint и вызывать функцию DLL следующим образом:

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