DELPHI FAQ: Простой пример


Простой пример
Previous  Home  Next


Итак, попробуем рассказать в простоте. Вот есть у вас класс - примитивный калькулятор:

MyCalc=class

fx,fy:integer; 
public
:
procedure SetOperands(x,y:integer) 
function Sum:integer; 
function Diff:integer; 
end
;

procedure
 MyCalc.SetOperands(x,y:integer)
begin

fx:=x; fy:=y; 
end
;

function
 MyCalc.Sum:integer;
begin

result:=fx+fy; 
end
;

function
 MyCalc.Diff:integer;
begin

result:=fx-fy; 
end
;

Все элементарно. Теперь если у вас есть объект этого класса, то вам не составит труда им воспользоваться.
Но представим следующую ситуацию: у вас есть один модуль, где объявлется объект этого класса. Допустим:

unit MyCalc

type

MyCalc=class

<описание выше>

var

Calc:MyCalc;



и теперь вы хотите использовать в другом модуле. Хорошо, скажите Вы, мы его просто подключим, и используем. Но, допустим, вы хотите, чтобы и другие могли пользоваться вашим объектом, даже используея другой компилятор. То есть нужно сделать так, чтобы ваш модуль можно было бы использовать без перекомпиляции. Как это сделать?

Ясно, что без каких-то стандартов не обойтись. Скорее всего, самый простой вариант выглядел бы так:

unit MyCalc

type

MyCalc=class 
<описание выше>

var 
Calc:MyCalc;

procedure
 SetOperands(x,y:integer)
begin

Calc.SetOperands(x,y);  
end
;

function
 Sum:integer;
begin

result:= Calc.Sum;  
end
;

function
 Diff:integer;
begin

result:= Calс.Diff; 
end
;

procedure
 CreateObject;
begin

Calc:=MyCalc.Create; 
end
;

procedure
 ReleaseObject;
begin

Calc.Free; 
end
;

откомпилировать этот юнит, посмотреть, по какому адресу находятся функции SetOperands, Sum, Diff, CreateObject и ReleaseObject и приложить документацию где эти адреса будут указанны. Теперь каждый сможет загрузить ваш модуль в память и по адресу указанном в вашей документации вызвать нужную функцию.

Понятно, чем такой подход череват. Это крайне не удобно. Но, эта проблема была поставленна давно, и теперь у нас есть стандартизированное соглашение об экспорте функций. То есть вместо того, чтобы писать для каждого модуля документацию с адресами функций при компиляции в заголовке модуля создается специальная стандартная таблица где указанны имена этих функций и их адреса (также указывается числовой индефикатор, который может быть использован вместо имени). Теперь уже лучше. Для того чтобы вызвать ваши функции, достаточно загрузить ваш модуль в память прочитать таблицу экспорта, и можно по именам в ней нати адреса функций и их вызвать. Так устроены DLL. Сейчас все это поддерживается компиляторами, и Windows API. То есть вам самому ничего этого делать не надо, а достаточно вызвать LoadLibrary, чтобы загрузить ваш модуль в память, и GetProcAddress чтобы получить адрес функции по имени.






DELPHI FAQ




EOMY TOP 100      Рейтинг@Mail.ru      Rambler's Top100