Инициализация и завершение работы DLL
Применительно к рассматриваемому нами примеру, модернизированный исходный код библиотеки DataCheck будет выглядеть так:
Листинг 28.3. Часть исходного кода динамической библиотеки DataCheck c функцией обратного вызова.
… {Часть исходного кода опущена (см. листинг 24.2)} exports IsValidlnt, IsValidDate index 1, IsValidTime index 2 name 'ValidTime', procedure DLLEntryPoint(Reason: Integer); begin case Reason of DLL_PROCESS_ATTACH: ShowMessage('Первая загрузка DLL'); DLL_PROCESS_DETACH:; DLL_THREAD_ATTACH: ShowMessage('Создан новый поток'); DLL_THREAD_DETACH:; end; end; begin DLLProc: = @DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH); end.
Процедура DLLEntryPoint обеспечивает простой показ сообщения о полученном значении параметра. В коде инициализации глобальной переменной DLLProc передается адрес процедуры DLLEntryPoint. Затем эта процедура вызывается явно с параметром DLL_PROCESS_ATTACH.
У недоверчивого читателя может возникнуть вопрос – а зачем городить такие сложности, если можно просто использовать код в секции инициализации? Дело в том, что этот код выполняется только при запуске DLL. Поэтому, как, например, вовремя уничтожить создаваемые в библиотеке объекты при завершении ее работы? Для этого можно использовать функцию обратного вызова:
Листинг 28.4. Создание и удаление объекта при загрузке и выгрузке динамической библиотеки DataCheck.
… (Часть исходного кода опущена (см. листинг 24.2)} exports IsValidlnt, IsValidDate index 1, IsValidTime index 2 name 'ValidTime', type TSomeObject = class(TObject) Fieldl: String; end; var FirstObj: TSomeObject; procedure DLLEntryPoint(Reason: Word); begin case Reason of DLL_PROCESS_ATTACH: begin FirstObj: = TSomeObject.Create; FirstObj.Fieldl: = 'Объект создан'; ShowMessage(FirstObj.Fieldl); end; DLL__PROCESS_DETACH: FirstObj. Free; DLL_THREAD_ATTACH: ShowMessage('Создан новый поток'); DLL_THREAD_DETACH:; end; end; begin DLLProc: = @DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH); end.
При завершении работы динамической библиотеки вызывается процедура, на которую указывает адрес, содержащийся в переменной ExitProc:
var ExitProc: Pointer;