...
...

Windows Dynamic Link Libraries (DLLs)

Сложно, наверное, найти хоть одного человека, серьезно работающего в среде Windows, который бы не сталкивался с файлами, имеющими расширение DLL. Рядового юзера может потрясти даже их количество на жестком диске родной машины. Большинство их "сидит" в "C:\WINDOWS\SYSTEM\", что не мешает, впрочем, появляться им даже в любимой папке "D:\GAMES\". А сколько покусано локтей при виде раздирающего душу на части сообщения от желанной игрушки по поводу невозможности найти ту или иную DLL-ину: "Необходимая библиотека ТАКАЯ-ТО.DLL не найдена". Откуда приходит эта "красная зараза"? Что они есть такое на самом деле? Кому они "служат"? Об этом и пойдет дальше речь.

Итак, с самого начала. Dynamic Link Library (DLL) являет собой ни что иное, как обычный исполняемый файл, в принципе, ничем не отличающийся от стандартного EXE-шника. Библиотекой такой модуль называется потому, что в большинстве случаев не может выполняться независимо, как обычное приложение, и представляет из себя всего лишь коллекцию данных и "пассивных кусков кода" (реализуемые функции), вызываемых внешними приложениями или другими библиотеками в процессе их работы.

Что же побуждает разработчика ПО выносить подпрограммы в библиотеки, когда гораздо проще оставить их как есть - в теле основной программы? Ведь использование DLL ведет к потере целостности приложения, т.е. его корректная работа зависит от наличия необходимых библиотек на диске. Если DLL подключается к основной программе статически и нужная библиотека отсутствует, то приложение даже не запустится, а операционная система вернет сообщение об ошибке (как раз повод для неразумеющих помянуть непотребным словом разработчиков этой самой ОС). В случае же динамического подсоединения решение о дальнейших действиях принимать основной программе - т.е. либо опять же культурно сообщить пренеприятнейшую весть настроившемуся отдохнуть геймеру и предложить поискать эту самую затерявшуюся DLL самостоятельно, либо тихонько "промолчать", а потом так же тихонько "загнуться" вместе с виндой (снова повод охаять глючную мастдайку). Еще один бич - различные версии этих самых DLL. Суть тут вот в чем. Однажды написав, к примеру, сommdlg32.dll (библиотека, занимающаяся организацией стандартных диалоговых окон Windows), Microsoft на достигнутом не остановилась, и выпуская очередную версию Word-а, решила расширить функциональные возможности окошка открытия файлов (предварительный просмотр документа, к примеру) и импортировала в уже существующую библиотеку необходимые новые функции. Почему не написать сие специально под Word и "не трогать" стандартные файлы? А какой нормальный программер удержит в голове информацию о том, куда он "всунул" все подобного рода довески? И где гарантия, что такое вот улучшенное окошко не понадобится в Excel? Это считается достаточным основанием для создания новой версии соответствующей DLL. Для обратной совместимости категорически не рекомендуется переписывать или удалять старые функции библиотеки - обычно их просто оставляют как есть, только добавляя новые. А теперь представьте себе, сколько бесполезного "мусора" "для совместимости" лежит у нас в "C:\WINDOWS\SYSTEM\"! Очень часто встречаются в Windows 95-98 отдельные "монстры", тянущие за собой функции из далекой 16-ти битной(!) 3.11-ой. А глюк сам, собственно, начинается тогда, когда более новая версия DLL заменяется на более старую при инсталляции какого-либо антикварного софта. Описание подобных проблем и методов их решения часто встречается на страницах компьютерной прессы.

Это, так сказать, были, как говорят они - disadvantages. Поговорим о преимуществах. Так что же, все-таки, на самом деле побуждает программиста ввязываться в написание DLL (по многим, чисто техническим причинам, занятие сие не считается особенно приятным)? При более детальном изучении предмета нашего с вами разговора в душу ко мне просочилось (супротив "общепринятой-минус-системных-программистов-и-сисадминов прогламерской морали") чувство уважения к маме Microsoft (думается мне, идея использования технологии динамических библиотек в Windows без него не обошлась) - уж больно хороша идея. Во-первых, DLLs обеспечивают связь с между различными языками программирования, т.е. независимость от выбранного. Однажды написанные, скажем, на Delphi и скомпилированные в виде DLL процедуры, могут с успехом вызываться из любых Windows-приложений, созданных с помощью совершенно других компиляторов. Есть тут одна проблема, которая называется различные способы передачи параметров (calling conventions) функциям (в регистрах, через с стек, и т.д.), но это уже чисто технический момент и в данной статье я не собираюсь подробно на этом останавливаться. Во-вторых, при использовании внешних библиотек сокращается размер основной программы. Пока вы не "трогаете" специальных инструментов, предположим, в Microsoft Word, он и не знает о них, но лишь только вам захотелось вставить в документ таблицу, как тут же подгружается соответствующая библиотека, которая, собственно и содержит все необходимые функции для организации вашей фантазии. Третье: технология Plug-In-ов тоже, кстати, построена именно на DLL. Plug-Ins - не что иное как дополнительные наборы функций, подключаемые к основной программе. А качестве примеров можно привести небезызвестный WinAmp с его музыкальными фильтрами, популярную консольную оболочку File and ARchive Manager (FAR) а так же Photoshop опять же с фильтрами, но только графическими. Эта технология дает возможность разрабатывать подобные расширения фирмам - не производителям данных продуктов. А что такое апгрейд интерфейса пользователя при установке на Windows 95 Internet Explorer-а 4.0? Да, по большей части, просто подмена старых библиотек новыми. Чуть не упустил один важный момент. Кто-то из читателей наверное ехидно улыбнулся, обнаружив, что файлы Plug In-ов Photoshop имеют расширение .8BF, что никоим образом на .DLL не похоже. Ну и что? Файл динамической библиотеки может вообще не иметь расширения. А "заглянув внутрь", любой продвинутый пользователь узнает знакомую сигнатуру стандартного Windows EXE-шника. Есть, кстати, возможность построить стандартное приложение, являющееся так же динамической библиотекой. Файл будет иметь расширение .EXE и вести себя как стандартная программа. Недавно тут проскользнула мысль про удаление исполнимого файла Internet Explorer-а из Windows 98 и последующие за этим глюки. Здесь ситуация практически такая. Еще одна и, пожалуй, самая важная причина создания DLL - использование различными приложениями одних и тех же функций. Если, допустим, Microsoft Excel и Microsoft Word используют одни и те же процедуры проверки орфографии, то нет смысла копировать их в оба приложения - удобнее и практичнее вынести их в библиотеку. В ситуации, когда два приложения одновременно используют одну и ту же DLL в памяти может присутствовать единственная копия библиотеки, что позволяет сэкономить оперативную память и уменьшить свопинг на диск. Тут возникает (как у кого, конечно) весьма очевидный вопрос: что происходит, когда приложение, использующее динамический модуль, выгружается из памяти? Сразу же за ним убивать и копию DLL нельзя, т.к. она еще может быть использована другими приложениями. Для этого операционная система "ведет счет" ссылкам на библиотеку. Если она была загружена десять раз, то и выгружена должна быть тоже десять раз. Только после того, как счетчик использования обнуляется, система удаляет копию DLL из оперативной памяти. Как я уже сказал, есть возможность безболезненного обновления таких модулей с сохранением совместимости. На этом основывается и идея after-market support (поддержка после продажи), а в Win32 Programmer's Reference в качестве примера на эту тему приводится DLL - расширение драйвера дисплея, который модернизируется для поддержки ранее недоступного железа.

Вернемся к вопросу "а почему именно C:\WINDOWS\SYSTEM\?". Думаю, мало кто не слышал об API (Application Programming Interface). Так вот, все его наборы функций реализованы именно в виде динамических библиотек. Наиболее жирные представители этого стада - kernel32.dll, user32.dll, gdi32.dll и т.д. Ясное дело, что их куда больше полусотни. Кто, вы думаете, занимается "рисованием" окошек, кнопочек, скролл-баров, меню, текстовых окошек, кто заставляет модем набирать телефонный номер, выводит документ на принтер? Любое самое простое приложение под Windows, со стандартным пользовательским интерфейсом уже только для создания и настройки пустого серенького окна использует десяток функций API, которые запросто обращаются еще к сотне таких же из других модулей. Представьте себе теперь, что представляет собой, к примеру, Microsoft Word изнутри!

Итак, системные библиотеки находятся в "C:\WINDOWS\SYSTEM\" с самого рождения. Далее, практически каждое (особенно a-la Microsoft) инсталлируемое приложение считает делом чести добавить туда что-нибудь свое, даже если это свое никем больше не используется. Это удобно хотя бы потому, что системная папка Windows прописана в системной переменной path, и поиск статически залинкованной библиотеки происходит именно там в случае отсутствия ее в родной папке приложения (даже если программистом при написании программы был указан конкретный путь). Все это, взятое вместе, и есть ответ на поставленный вопрос.

Функции, реализованные в DLL, можно четко разделить на два класса: внутренние и внешние. Внутренние функции доступны лишь внутри самой библиотеки, где они, собственно и объявлены, и чаще всего являются вспомогательными подпрограммами. Главная же роль достается внешним функциям, которые (и только они) могут быть вызваны другими модулями. Именно их имена "видны" в разделе Export Table при "быстром просмотре" (есть возможность взглянуть на исполнимые файлы изнутри с помощью этой стандартной утилиты Windows). Так же "видна" и Import Table - образно говоря, таблица имен использованных внешних модулей. Вообще говоря, библиотека может также экспортировать и данные (примером тому является файл moreicons.dll - набор разнообразных иконок Windows), но в большинстве случаев они, как и локальные процедуры, используются лишь для внутренних нужд DLL.

Александр Муравский

© Компьютерная газета

полезные ссылки
Корпусные камеры видеонаблюдения