Читаем Советы по Delphi. Версия 1.4.3 от 1.1.2001 полностью

<p>Передача функции как параметра</p>

Delphi 1

В нашем случае лучшим решением будет использование процедурного типа. Допустим, что 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.

<p>Проблема передачи записи</p>

Delphi 1

Может это не то, что вы ищете, но идея такая:

Определите базовый класс с именем, скажем, allrecs:

tAllrecs = class

 function getVal(field: integer): string; virtual;

end;

Затем создаем классы для каждой записи:

recA = class(tAllrecs)

 this: Integer;

 that: String;

 the_other: Integer;

 function getVal(field: integer): string; virtual;

end;

Затем для каждой функции класса определите возвращаемый результат:

function recA.getVal(field: integer); string;

begin

 case field of

 1: getVal := intToStr(this);

 2: getVal := that;

 3: getVal := intToStr(the_other);

 end;

end;

Затем вы можете определить

function myFunc(rec: tAllrecs; field: integer);

begin

label2.caption := allrecs.getVal(field);

end;

затем вы можете вызвать myFunc с любым классом, производным от tAllrecs, например:

myFunc(recA, 2);

myFunc(recB, 29);

(getVal предпочтительно должна быть процедурой (а не функцией) с тремя var-параметрами, возвращающими имя, тип и значение.)

Все это работает, т.к. данный пример я взял из моего рабочего проекта.

[Sid Gudes, cougar@roadrunner.com]

Перейти на страницу:

Похожие книги

Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript

Данная книга посвящена программированию игр с помощью ActionScript. Здесь вы найдете подробные указания, необходимые для создания самых разных игр – аркад, головоломок, загадок и даже игровых автоматов. В тексте приведены исходные коды программ и детальные, доступно изложенные инструкции. Базовые принципы программирования ActionScript рассматриваются на примере игр, однако вы без труда сможете применить полученные знания и для разработки неигровых проектов, таких как Web-дизайн и реклама. Рекомендации Гэри Розенцвейга помогут вам не только придумывать занимательные игры и размещать их на Web-сайте, но и оптимизировать скорость их работы, а также защищать свои творения от несанкционированного копирования. Представленный в книге код несложно изменить для использования в других программах.Книга предназначена для широкого круга читателей – создателей анимационных роликов, художников-оформителей, программистов и разработчиков Web-сайтов. Издание может также выступать в качестве практического пособия по изучению ActionScript.

Гэри Розенцвейг

Программирование, программы, базы данных / Программирование / Книги по IT
iOS. Приемы программирования
iOS. Приемы программирования

Книга, которую вы держите в руках, представляет собой новый, полностью переписанный сборник приемов программирования по работе с iOS. Он поможет вам справиться с наболевшими проблемами, с которыми приходится сталкиваться при разработке приложений для iPhone, iPad и iPod Touch. Вы быстро освоите всю информацию, необходимую для начала работы с iOS 7 SDK, в частности познакомитесь с решениями для добавления в ваши приложения реалистичной физики или движений — в этом вам помогут API UIKit Dynamics.Вы изучите новые многочисленные способы хранения и защиты данных, отправки и получения уведомлений, улучшения и анимации графики, управления файлами и каталогами, а также рассмотрите многие другие темы. При описании каждого приема программирования приводятся образцы кода, которые вы можете смело использовать.

Вандад Нахавандипур

Программирование, программы, базы данных / Программирование / Книги по IT