Шаг 303.
Создание внутрипроцессных серверов автоматизации. Создание и использование DLL. Статическая загрузка DLL

    На этом шаге мы рассмотрим статическую загрузку DLL.

    Модуль может вызывать функции другого модуля, тот, в свою очередь, функции следующего и т. д. Например, приложение вызывает библиотеку, а эта библиотека вызывает функции другой библиотеки - так можно формировать длинные цепочки вызовов. Для вызова функции из другого модуля необходимо сначала загрузить ее в память, а затем определить адрес функции. Существует два способа загрузки и определения адреса функции - статический и динамический.

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

function Addl(K: Integer): Integer; stdcall;
  external 'FirstLib.dll' name 'CalculateSum'; 
function Add1(K: Integer): Integer; stdcall;
  external 'FirstLib.dll' index 1;

    Для тестирования необходимо описать в приложении внешнюю функцию одним из вышеупомянутых способов и создать, например, обработчик события OnClick кнопки, помещенной на форму вместе с компонентом TEdit:

procedure TForm1.Button1Click(Sender: TObject);
var
  N: Integer;
begin
  N := StrToInt(Edit1.Text);
  N := Add1(N);
  Edit1.Text := IntToStr(N);
end;
Текст этого приложения вместе с DLL можно взять здесь (252,3 Кб).

    Результат работы приложения изображен на рисунке 1.


Рис.1. Результат работы приложения

    При щелчке на кнопке будет вызываться функция из DLL. Обратите внимание на изменение имени функции: из обработчика события OnCiick вызывается функция с именем Add1. Эта функция экспонируется в DLL под именем CalculateSum. В реализации DLL она имеет название AddOne.

    При таком определении функции библиотека будет загружена немедленно после старта приложения и выгружена вместе с его завершением. В приведенном примере следует обратить внимание на то, что после имени библиотеки указано ее расширение (FirstLib.dll). Такая конструкция необходима для загрузки библиотеки в Windows NT, Windows 2000 и Windows XP - без расширения *.dll файл найден не будет. Для работы приложения под управлением Windows 95/98 указывать расширение не обязательно.

    При поиске DLL для загрузки первоначально определяется, была ли данная библиотека уже загружена в память другим модулем. Если была - извлекается адрес вызываемой функции и затем передается приложению. Если же нет - операционная система начинает ее поиск на диске. При этом если в имени DLL путь не указан в явном виде, то операционная система ищет библиотеку в каталоге модуля, пытающегося загрузить DLL. Если не находит - то продолжает поиск в каталогах WINDOWS и WINDOWS | SYSTEM (или WINNT, WINNT | SYSTEM, WINNT | SYSTEM32). После этого происходит поиск в каталогах, определенных в переменной среды Path. Если операционная система обнаруживает библиотеку с заданным именем, она загружает эту библиотеку и приложение стартует. Если же нет - возникает исключение и приложение прекращает свою работу. Приложение также прекращает свою работу, если не найдена функция с данным именем (или индексом, если она импортируется по индексу).

    На следующем шаге мы рассмотрим динамическую загрузку DLL.




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