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 (1 Создан новый поток ' ) ;
DLL_THREAD_DETACH:;
end;
end;
begin
DLLProc := SDLLEntryPoint;
DLLEntryPoint(DLL_PROCESS__ATTACH);

end.

Процедура DLLEntryPoint обеспечивает простой показ сообщения о полученном значении параметра. В коде инициализации глобальной переменной

DLLProc передается адрес процедуры DLLEntryPoint. Затем эта процедура вызывается явно с параметром dll_process_attach.

У недоверчивого читателя может возникнуть вопрос - а зачем городить такие сложности, если можно просто использовать код в секции инициализации? Дело в том, что этот код выполняется только при запуске DLL. Поэтому, как, например, вовремя уничтожить создаваемые в библиотеке объекты при завершении ее работы? Для этого можно использовать функцию обратного вызова:

Листинг 28.4. Создание и удаление объекта при загрузке " . " • .г-:" ■'" 'j ивыгрузкединамическойбиблиотеки0ат.аСпеск " , - гЧ/^т'^'!

{Часть исходного кода опущена (см. листинг 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__PR0CESS_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.

При завершении работы динамической библиотеки вызывается процедура, на которую указывает адрес, содержащийся в переменной ExitPrcc:

varExitProc: Pointer;

Вызов DLL

Теперь рассмотрим, как из динамических библиотек вызываются функции.

При запуске исполняемого файла приложения операционная система создает для его работы отдельный процесс. Также система создает первичный поток, владельцем которого является процесс. Процесс приложения получает 4 Гбайт адресного пространства, в которое отображается исполняемый код приложения.

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

В результате при обращении приложения к функции из DLL вся информация о ней уже имеется в процессе. Для выполнения функции (вызов осуществляется одним из потоков процесса приложения) в адресное пространство процесса приложения загружается соответствующая динамическая библиотека. После этого исполняемый код DLL становится полностью доступен внутри процесса, но не вне его. Другие процессы могут загрузить эту же библиотеку и использовать ее образ в собственном адресном пространстве. Именно поэтому несколько приложений могут применять одну динамическую библиотеку одновременно.


⇐ Предыдущая страница| |Следующая страница ⇒

Программирование в Delphi 7



Новости за месяц

  • Декабрь
    2017
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс