Руководство по языку B.Pascal 7

       

Код инициализации библиотеки


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

DLL хранится в памяти, пока ее счетчик использования больше нуля. Когда счетчик использования становится нулевым, указывая, что все использующие DLL прикладные программы завершили работу, она удаляется из памяти. При этом выполняется код процедуры выхо- да. Процедуры выхода регистрируются с помощью переменной ExitProc, которая описывается в Главе 22 "Вопросы управления".

Код инициализации DLL обычно выполняет такие задачи как ре- гистрация класса окна для содержащихся в DLL оконных процедур и установка начальных значений для глобальных переменных DLL. Уста- новив в нулевое значение переменную ExitCode, код инициализации библиотеки может указать состояние ошибки (ExitCode описывается в модуле System). По умолчанию ExitCode равна 1, что указывает на успешную инициализацию. Если код инициализации устанавливает зна- чение этой переменной в 0, то DLL выгружается из системной памя- ти, и вызывающая прикладная программа уведомляется о неудачной загрузке DLL.

Когда выполняется библиотечная процедура выхода, переменная ExitCode не содержит код завершения процесса. Вместо этого ExitCode содержит одно из значений wep_System или wep_Free_DLL, определенных в модуле WinTypes. wep_System указывает на заверше- ние работы Windows, а wep_Free_DLL указывает на то, что выгружена данная DLL.

Приведем пример библиотеки с кодом инициализации и процеду- рой выхода:

library Test;

{$S-}

uses WinTypes, WinProcs;

var SaveExit: Pointer;

procedure LibExit; far; begin if ExitCode = wep_System_Exit then begin . .

{ выполняется завершение работы системы } . . . end else begin . . . { разгружается DLL } . . . end; ExitProcess : SaveExit; end;

begin . . . { выполнить инициализацию DLL } . . . SaveExit := ExitProc; { сохранить старый указатель процедуры выхода } ExitProc := @LibExit; { установка процедуры выхода LibExit } end.


В защищенном режиме DOS передаваемое процедуре выхода DLL значение ExitCode всегда равно 0 и соответствует wep_FREE_DLL.

После разгрузки DLL экспортируемая функция вызывает процеду- ру WEP (процедура выхода Windows) DLL, если она присутствует. Библиотека Borland Pascal автоматически экспортирует функцию WEP, которая продолжает вызывать записанный в переменной ExitProc ад- рес, пока ExitProc не примет значения nil. Поскольку этот меха- низм процедур выхода соответствует работе с процедурами выхода в программах Borland Pascal, и в программах, и в библиотеках вы мо- жете использовать одну и ту же логику процедур выхода.

Поскольку операционная система при завершении DLL переключа- ет внутренний стек, процедуры выхода в DLL должны компилироваться с запрещением проверки стека (в состоянии {$S-}). Кроме того, ес- ли в процедуре выхода DLL происходит ошибка этапа выполнения, операционная система аварийно завершает работу, поэтому вы для предотвращения ошибок этапа выполнения вы должны включить в свой код достаточное количество проверок.


Содержание раздела