Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001
- Название:Советы по Delphi. Версия 1.4.3 от 1.1.2001
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001 краткое содержание
…начиная с 1001. Смотрите другие файлы…
Советы по Delphi. Версия 1.4.3 от 1.1.2001 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
functionfoo: integer;
begin
result := 1;
end;
begin
MyFunc := foo;
DllFunction(longint(MyFunc));
Вы можете это сделать и так:
DllFunction(longint(@foo));
Все же я не уверен в вопросах корректности использования таким образом в вызовах DLL памяти (для меня пока неясна работа с памятью, находящейся в другом сегменте), как в этом примере, так что возможно для корректной работы вам придется объявить foo с директивой far, экспортировать ее в модуле, или что-то еще.
Также, в зависимости от того, как написана DllFunction(), вы можете в вызове подразумевать приведение типа:
functionDllFunction(p: TMyFuncType): Integer; far; external'mydll';
В этом случае вам не нужна будет переменная MyFunc или оператор @.
В Delphi/Pascal вы можете передавать функции как параметры. Тем не менее, чтобы этим воспользоваться, необходимо для компилятора установить тип. Попробуйте следующий код (я реально его компилил и тестировал):
unitUnit1;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedureButton1Click(Sender: TObject);
procedureButton2Click(Sender: TObject);
private{ Private declarations }
public{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
type
IntFunc = function: integer;
functionDllFunction(iFunc: IntFunc): integer; far;
begin
DllFunction := iFunc; {Обратите внимание на то, что это вызов функции}
end;
functioniFoo: integer; far;
begin
iFoo := 1;
end;
procedureTestIFunc;
var
i: integer;
begin
i := DllFunction(iFoo);
end;
procedureTForm1.Button1Click(Sender: TObject);
begin
TestIFunc;
end;
procedureTForm1.Button2Click(Sender: TObject);
begin
Close;
end;
end.
Вы можете сделать две вещи. Во-первых, если вы хотите использовать для передачи longint, напишите следующий код:
i := longint(@foo)
Другая вещь, которую вы можете сделать — исключить работу с longint и вызывать функцию dll следующим образом:
DLLfunction(@foo);
Имейте в виду, что если вы собираетесь вызывать foo из DLL, то необходимо предусмотреть вопросы совместимости, для получения дополнительной информации почитайте описание функции MakeProcInstance.
Проблема передачи записи
Delphi 1
Может это не то, что вы ищете, но идея такая:
Определите базовый класс с именем, скажем, allrecs:
tAllrecs = class
functiongetVal(field: integer): string; virtual;
end;
Затем создаем классы для каждой записи:
recA = class(tAllrecs)
this: Integer;
that: String;
the_other: Integer;
functiongetVal(field: integer): string; virtual;
end;
Затем для каждой функции класса определите возвращаемый результат:
functionrecA.getVal(field: integer); string;
begin
casefield of
1: getVal := intToStr(this);
2: getVal := that;
3: getVal := intToStr(the_other);
end;
end;
Затем вы можете определить
functionmyFunc(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]
Если вы хотите за один раз передавать целую запись, установите на входе ваших функций/процедур тип 'array of const' (убедитесь в правильном приведенни типов). Это идентично 'array of TVarRec'. Для получения дополнительной информации о системных константах, определяемых для TVarRec, смотри электронную справку по Delphi.
Указатели
Указатель на функцию I
Delphi 1
Это то, что я нашел при создании простой машины состояний:
Ниже приведен простой пример для Borland Delphi, использующий указатели функций для управления программным потоком. Просто создайте простую форму с единственной кнопкой и скопируйте код из Unit1 во вновь созданный модуль. Добавьте к проекту Unit2 и скомпилируйте проект. Дайте мне знать, если у вас возникнут какие-либо проблемы.
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedureButton1Click(Sender: TObject);
private{ Private declarations }
public{ Public declarations }
end;
var
Form1: TForm1;
CurrProc : LongInt;
MyVal : LongInt;
implementation
usesUnit2;
{$R *.DFM}
procedureTForm1.Button1Click(Sender: TObject);
var
NewProc : LongInt;
MyString : string;
begin
CurrProc := 2; { начальная точка в таблице методов }
MyVal := 0; { вспомогательная переменная }
NewProc := 0; { возвращаемое значение для следующего индекса в таблице методов }
whileCurrProc < 6 do begin
{ выполняем текущий индекс в таблице методов и получаем следующую процедуру }
NewProc := ProcTable[CurrProc](MyVal);
{ просто показываем значения NewProc и CurrProc }
FmtStr(MyString, 'NewProc [%d] CurrProc [%d]', [NewProc, CurrProc]);
MessageDlg(MyString, mtInformation, [mbOK], 0);
{ присваиваем текущую процедуру возвращаемой процедуре }
CurrProc := NewProc;
end;
end;
end.
{ Это простой пример, определяющий массив указателей на функции }
interface
type
{ определяем Procs как функцию }
Procs = function( varProcNum : LongInt): LongInt;
var
{ объявляем массив указателей на функции }
ProcTable : Array[1..5] ofProcs;
{ определения интерфейсов функций }
functionProc1( varMyVal : LongInt) : LongInt; far;
functionProc2( varMyVal : LongInt) : LongInt; far;
functionProc3( varMyVal : LongInt) : LongInt; far;
functionProc4( varMyVal : LongInt) : LongInt; far;
Интервал:
Закладка: