Шаг 112.
Создание динамически подключаемых библиотек

    На этом шаге мы рассмотрим создание DLL в Delphi.

    Структура динамически подключаемой библиотеки практически такая же, как и структура проекта. Отличие состоит только в том, что в заголовке вместо зарезервированного слова program записывается зарезервированного слово library. Это слово указывает компилятору, что требуется создать выполняемый файл динамически подключаемой библиотеки, который должен иметь расширение .DLL, а не .ЕХЕ.

    Приведем простейший демонстрационный пример использования DLL для создания пользователем собственной сервисной библиотеки процедур и функций.

library proba;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes;

{$R *.res}

function Vect_Max  (Vect: array of Integer; N:Word) : Integer; export;
var
  Max : Integer;
  i   : Word;
begin
  Max := Vect[0];
  for i := 1 to N-1 do
    if Vect[i] > Max then Max := Vect[i];
  Result := Max;
end;

function Vect_Min (Vect: array of Integer; N:Word) : Integer; export;
var
  Min : Integer;
  i   : Word;
begin
  Min := Vect[0];
  for i := 1 to N-1 do
    if Vect[i] < Min then Min := Vect[i];
  Result := Min;
end;

exports
  Vect_Max index 1,
  Vect_Min index 2;
begin
{ Раздел инициализации отсутствует }
end.
Текст этого примера можно взять здесь.


    Замечание. В Delphi имеется возможность создания "заготовки" для DLL. Для этого нужно, предварительно закрыв все проекты, выполнить File | New | Other... и в появившемся окне на вкладке New выбрать DLL Wizard:


Рис.1. Вкладка New

    Для получения DLL проект нужно сначала сохранить, а потом откомипилировать, выполнив, например, пункт меню Project | Build <Имя проекта>


    В описании динамически связываемых библиотек важная роль принадлежит предложению exports (с буквой "s" в конце), которое рассмотрено на шаге 17, и процедурной директиве ехроrt (без буквы "s" в конце), которая указывается в заголовках экспортируемых из создаваемой DLL процедур и функций. Директива export принудительно использует для процедуры или функции дальний тип вызова и подготавливает ее для экспортирования, генерируя для процедуры/функции специальный код входа и выхода. Однако фактический экспорт процедуры/функции не произойдет до тех пор, пока она не будут указана в предложении exports описываемой библиотеки.

    Операторы раздела инициализации выполняются, как и у модуля, однократно, но не при запуске программы, а при первоначальной загрузке библиотеки. Для определения потребности нахождения DLL в оперативной памяти служит, так называемый счетчик использования DLL. Для каждой DLL устанавливается свой счетчик использования DLL, который показывает, сколько программ в данный момент времени ее используют. Динамически загружаемая библиотека после загрузки хранится в памяти до тех пор, пока ее счетчик использования больше нуля. Когда все прикладные программы, использующие DLL, заканчивают работу, значение счетчика ее использования становится нулевым и DLL удаляется из памяти. Если какую-либо уже загруженную DLL начинает использовать еще одна программа, счетчик ее использования увеличивается, а операторы раздела инициализации повторно не выполняются.

    Со следующего шага мы начнем знакомиться с использованием процедур и функций, находящихся в DLL.




Предыдущий шаг Содержание Следующий шаг