Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Использование DLLProc



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

Для начала следует сказать о самой причине существования DLLProc. Динамическая библиотека получает сообщения от Windows в моменты своей загрузки и выгрузки из оперативной памяти, а также в тех случаях, когда какой-нибудь очередной процесс, использующий функции и/или ресурсы, хранящиеся в библиотеке, загружается в память. Такая ситуация возможно в том случае, когда библиотека необходима для функционирования нескольких приложений. А для того, чтобы вы имели возможность указывать, что именно должно происходить в такие моменты, необходимо описать специальную процедуру, которая и будет ответственна за такие действия. К примеру, она может выглядеть следующим образом:

procedure MyFirstDLLProc(Reason: Integer);

begin

if Reason = DLL_PROCESS_DETACH then

{DLL is unloading. Cleanup code here.}

end;

Однако системе совершенно не очевидно, что именно процедура MyFirstDllProc ответственна за обработку рассмотренных выше ситуаций. Поэтому вы должны поставить в соответствие адрес нашей процедуры глобальной переменной DLLProc. Это необходимо сделать в блоке begin...end примерно так:

begin

DLLProc:= @MyDLLProc;

{ Что-нибудь еще, что должно выполняться в

процессе инициализации библиотеки }

end.

Ниже представлен код, демонстрирующий один из возможных вариантов применения DLLProc.

library MyFirstDLL;

uses

SysUtils,

Classes,

Forms,

Windows;

var

SomeBuffer: Pointer;

procedure MyFirstDLLProc(Reason: Integer);

begin

if Reason = DLL_PROCESS_DETACH then

{DLL is выгружается из памяти.

Освобождаем память, выделенную под буфер.}

FreeMem(SomeBuffer);

end;

procedure HelloWorld(AForm: TForm);

begin

MessageBox(AForm.Handle, Hello world!',

DLL Message Box', MB_OK or MB_ICONEXCLAMATION);

end;

{Какой-нибудь код, в котором используется SomeBuffer.}

exports

HelloWorld;

begin

{Ставим в соответствие переменной

DLLProc адрес нашей процедуры.}

DLLProc:= @MyFirstDLLProc;

SomeBuffer:= AllocMem(1024);

end.

Как можно увидеть, в качестве признака того или иного события, в результате которого вызывается процедура MyFirstDll, является значение переменной Reason. Ниже приведены возможные значения этой переменной.

DLL_PROCESS_DETACH - библиотека выгружается из памяти; используется один раз;

DLL_THREAD_ATTACH - в оперативную память загружается новый процесс, использующий ресурсы и/или код из данной библиотеки;

DLL_THREAD_DETACH - один из процессов, использующих библиотеку, "выгружается" из памяти.





Дата публикования: 2015-02-18; Прочитано: 326 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.006 с)...