Главная » Delphi » Динамически компонуемые библиотеки

0

Что такое библиотека DLL?

Динамически  компонуемые библиотеки —  это  программные  модули,  содержащие код, данные или  ресурсы, которые могут совместно использоваться несколькими при ложениями Windows.  Одно  из основных назначений библиотек DLL —  позволить при ложениям загружать  участки  кода во время  выполнения (динамически), а не компоно вать их в само приложение в процессе компиляции (статически). Как следствие, один и тот  же код,  содержащийся в библиотеке DLL,  смогут одновременно использовать не сколько  приложений. Так, файлы библиотек Kernel32.dll, User32.dll и GDI32.dll являются теми тремя  китами, на которые опирается система  Win32. Файл Ker- nel32.dll (ядро), например, отвечает за управление памятью, процессами и потоками. Файл User32.dll содержит функции пользовательского интерфейса, необходимые для создания окон  и обработки сообщений Win32. И, наконец, на файл  GDI32.dll возло жена работа с графикой. Существуют и другие системные библиотеками DLL, например AdvAPI32.dll и ComDlg32.dll, которые предназначены для обеспечения работы с системным реестром и диалоговыми окнами общего назначения.

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

С точки  зрения файловой системы, библиотеки DLL практически ничем  не отли чаются  от  исполняемых файлов Windows  (EXE).  Разница состоит лишь  в том,  что файл  библиотеки DLL не является независимым исполняемым файлом, хотя  может  со держать исполняемый код.  Чаще  всего  файлы библиотек DLL  имеют  расширение

.dll. Но  могут  встречаться и другие:  .drv —  для  драйверов устройств,  .sys —  для системных файлов, .fon —  для файлов ресурсов шрифтов, которые не содержат ис полняемого кода.

НА ЗАМЕТКУ

В Delphi используются специальные библиотеки, называемые пакетами. Они приме- няются не только в среде Delphi, но и в среде Borland C++ Builder. Более подробная информация о пакетах приведена в главе 14, “Пакеты”.Библиотеки DLL способны использовать свой  код совместно с другими  приложе ниями благодаря процессу, называемому динамической  компоновкой (dynamic linking), который рассматривается в этой  главе  далее.  Как  правило, когда  какое либо  прило жение использует библиотеку  DLL,  система  Win32  гарантирует, что  в памяти будет размещена только  одна копия  этой  библиотеки. Для этого  применяется файл, отобра женный в память (memory mapped file). Суть этого  метода  заключается в том, что биб лиотека DLL сначала  загружается в глобальную  распределяемую память (heap) системы Win32, а затем  отображается на адресное пространство вызывающего процесса. В системе Win32 каждому процессу  выделяется собственное непрерывное 32 разрядное адресное пространство. Поэтому, когда одна и та же библиотека DLL загружается сразу несколькими процессами, каждый  из них получает  собственный образ (image) данной  библиотеки. Следовательно, процессы не используют одновременно один  и тот же  физический код,  данные или  ресурсы, как  это  было  в  16 разрядной Windows. В системе Win32 работа организована так, что библиотека DLL становится как бы ре альным  кодом,  принадлежащим вызывающему процессу.  Более  подробная информа ция  о работе системы Win32  приведена в предыдущем издании Delphi 5 Руководство разработчика, в главе 3 — “Win32 API”.

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

Установка  предпочтительного базового  адреса библиотеки DLL

Совместный доступ нескольких процессов к коду библиотеки DLL возможен только в том случае, если эту библиотеку можно загрузить в адресное пространство процессов всех заинтересованных клиентов по некоторому предпочтительному базовому адресу (preferred base address) библиотеки DLL. Если предпочтительный базовый адрес, с учетом размера библиотеки DLL, перекрывается каким-либо другим объектом, уже размещенным в памяти процесса, то загрузчик Win32 должен будет изменить распо- ложение всего образа библиотеки DLL, используя другой базовый адрес. В этом слу- чае ни один из перемещенных образов DLL не может использоваться никакими други- ми процессами в системе, т.е. каждый перемещенный экземпляр библиотеки DLL за- нимает участок собственной физической памяти и собственную часть пространства файла подкачки.

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

$IMAGEBASE.

Если библиотека DLL предназначена для использования несколькими приложениями,

то необходимо выбрать уникальный базовый адрес, который с минимальной вероятно- стью будет перекрываться адресами приложения в области младших значений диапа- зона виртуальных адресов или общих библиотек DLL (например пакетов VCL) в облас- ти старших адресов диапазона. По умолчанию базовый адрес всех исполняемых фай- лов  (с  расширениями  .EXE и  .DLL)  равен  $400000,  а  это  означает,  что  если  не изменить базовый адрес конкретной библиотеки DLL, то конфликт с базовым адресом

1 Копию, экземпляр. — Прим. ред.ее главного файла EXE будет неизбежен и она никогда не будет совместно использо-

ваться всеми заинтересованными процессами.

В применении базового адреса есть еще один положительный момент. Поскольку биб- лиотека DLL не требует изменения расположения или внесения исправлений (что обычно и происходит) и сохраняется на локальном диске, страницы ее памяти отобра- жаются прямо в файл DLL на диске. Код DLL не занимает никакого пространства в сис- темном файле подкачки (page file) (он же файл подкачки страниц (swap file), он же

файл страничного обмена). Вот почему общее количество и размер выгружаемых сис- темой на диск страниц может намного превышать размеры системного файла подкач- ки и объем RAM.

Более подробная информация об использовании директивы $IMAGEBASE приведена в

разделе “Image Base Address” интерактивной справочной системы Delphi 6.

Прежде чем продолжить обсуждение данной темы,  необходимо уточнить некоторые термины.

•    Приложение  (application).  Программа  Windows,  размещенная  в  файле  с  расширением .exe.

•    Исполняемый  файл  (executable).  Файл,  содержащий  исполняемый  код.  Исполняемые файлы имеют расширения .dll и .exe.

•  Экземпляр (instance). Когда  речь  идет  о  приложениях или  библиотеках DLL, термин экземпляр означает отдельный процесс выполнения исполняемого файла. Каждому  экземпляру соответствует дескриптор экземпляра (instance handle), ко торый назначается системой Win32. Например, когда приложение запускается дважды,  в памяти образуется два экземпляра данного приложения и,  следова тельно, два дескриптора экземпляра. Но при загрузке  библиотеки DLL создает ся только  один  экземпляр этой  библиотеки и,  соответственно, один  дескрип тор  экземпляра. Используемый здесь  термин экземпляр не  следует  путать  с эк земпляром класса.

•  Модуль (module). В 32 разрядной Windows  (в отличие от 16 разрядной) термины модуль и экземпляр могут использоваться как синонимы2. В 16 разрядной Windows для управления модулями существует специальная база данных, в которой для ка ждого модуля хранится свой дескриптор. В 32 разрядной Windows каждый  экзем пляр  приложения получает собственное адресное пространство, следовательно, нет  нужды в образовании отдельного идентификатора  модуля.  Но  корпорация Microsoft в своей  документации по прежнему использует этот термин. Поэтому  не обходимо просто иметь в виду, что модуль и экземпляр означают одно и то же.

•  Задача (task). Система  Windows является многозадачной средой (или  средой с пе реключением задач).  Она  должна  обладать  способностью распределять систем ные  ресурсы  и время  между различными экземплярами приложений, работаю щих под ее управлением. Для этого  система  поддерживает базу данных  задач,  в которой хранятся дескрипторы экземпляров и другая информация, позволяющая системе переключаться между задачами. Таким  образом, задача —  это  элемент, для которого Windows выделяет ресурсы и периоды времени выполнения.

2 Речь идет о загружаемом модуле (module), а не о модуле программы (unit). — Прим. ред.

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии