Динамически компонуемые библиотеки

advertisement
Динамически компонуемые библиотеки
Цель: изучить библиотеки DLL (Dynamic Library Link или динамически подключаемые
библиотеки), понять, где, каким образом и когда нужно использовать DLL-файлы.
Проблема
Пока существовали однозадачные операционные системы, проблема с излишней тратой
дискового пространства была единственной. Но как только появились многозадачные
операционные системы ( например Windows), сразу возникла другая проблема.
Представьте себе ситуацию, когда вы запускаете две программы (программы имеют
одинаковые фрагменты кода) одновременно. При старте любой код грузится в
оперативную память и только потом выполняется. Таким образом получается, что обе
программы загрузят в память один и тот же код. Такая ситуация нежелательна.
Решение № 1
Одним из первых решений этой задачи стало использование модульного
программирования. Программист пишет определенную часть программы, оформляет ее в
виде модуля, а потом просто использует этот модуль в своих программах. В качестве
модуля может выступать подпрограмма-процедура, подпрограмма-функция и собственно
модуль (Unit). При использовании заранее разработанных и отлаженных модулей не надо
каждый раз выдумывать велосипед - добавляете к своей программе определенный модуль
и используете когда-то написанный вами или кем-то другим программный код. И до
настоящего времени это один из основных технологических приёмов написания
программ.
Однако с появлением многозадачности программисты и простые пользователи заметили,
что эффективность программ стала снижаться.
Решение № 2
Идея состоит в том, чтобы не стыковать модули с основной программой, а сохранять их в
отдельный файл, и пусть любая программа загружает их по мере надобности. Так
появились библиотеки DLL. Эти библиотеки подключаются к программе динамически. В
них можно хранить исполняемый код в виде процедур или функций, ресурсы программы,
графику или даже видеоролики.
В этом случае программа не увеличивается на размер модуля при компиляции, а
загружает код из DLL-файла в память, а затем использует его. Если одна программа уже
загрузила DLL, то следующая не будет делать этого. Она воспользуется уже загруженной
версией. Таким образом, экономится не только место на диске, но и оперативная память.
Основная идея: при использовании динамических библиотек в исполняемом файле находится только самое основное, а дополнительные возможности подгружаются по мере
надобности из DLL-файлов. Например, когда стартует Word, то загружается только
модуль текстового редактора. Когда вы выбрали редактор формул Microsoft Equation или
объект WordArt, то Word подгружает из DLL-файла код выбранного объекта и выполняет
его. Таким образом, суммарная скорость загрузки уменьшается, причем очень
значительно.
Еще одно большое преимущество динамических библиотек — при их использовании код
программы разбивается на несколько файлов (зависит от количества DLL-файлов).
Допустим, что в одной из функций, находящихся в DLL-файле, оказался код с ошибкой. В
этом случае не надо обновлять всю программу, а достаточно передать всем пользователям
только этот DLL-файл, и программа получит необходимые обновления.
Две особенности динамических библиотек:
1. Код из DLL-файла выполняется в том же участке памяти, что и основная программа.
Поэтому программа и DLL-код используют один и тот же стек данных, что иногда
накладывает свои ограничения. Например, DLL-код не может хранить глобальных
переменных. Воспринимайте динамические библиотеки просто как набор процедур и
функций, которые могут хранить только локальные переменные.
2. Изначально динамические библиотеки были процедурными. Несмотря на это,
программы ActiveX (изначально объектные) могут храниться в файлах с расширением
dll и выполняют те же задачи, что и классические динамические библиотеки.
Графические программы
Существует программа для работы с графикой OpenGL.Она состоит из двух
динамических библиотек opengl.dll(opengl32.dll) и glu.dll(glu32.dll).
Программа DirectX - это графическая библиотека, которая состоит из файлов
DirectDraw, DirectInput, DirectMusic, DirectPlay и т. д. Все это не что иное,
как динамически подгружаемые библиотеки. DirectDraw это Ddraw.dll,
DirectInput это Dinput.dll, DirectMusic это Dmusic.dll и т. д. Хотя
DirectX это не простые библиотеки — это библиотеки, созданные на основе технологии
СОМ.
Любые «игровые движки» (набор функций для облегчения создания игры определенного
жанра с определенными возможностями) выполнены в виде динамически загружаемых
библиотек, потому что их использование очень простое и удобное для любого
программиста.
Выводы:
1. Динамические библиотеки практически ничем не отличаются от ЕХЕ-файлов. Это такой
же скомпилированный код, только он не может запускаться самостоятельно, потому что в
библиотеке нет точки входа (точки, с которой начинает свое выполнение любая
программа).
2. В DLL-файлах хранятся процедуры, функции и различные ресурсы, которые можно
вызывать из других программ.
3. Чаще всего динамические библиотеки имеют расширение dll, но можно установить и
любое другое расширение или вообще убрать его.
4. Библиотеки имеют свои разновидности, например, драйверы — это то же динамические
библиотеки и им принято давать расширение drv. Возможно также использование
расширения sys для системных файлов. Так что операционная система не накладывает
ограничений на расширения динамических библиотек, главное, чтобы программисту
было понятно и удобно работать.
5. Когда одно приложение загружает библиотеку, то она загружается ее в глобальную
память, а потом только проецируется в адресное пространство программы. Это значит, что
программа будет «видеть» функции библиотеки как свои собственные, хотя они
расположены совершенно в отдельном адресном пространстве.
6. Операционная система Windows гарантирует, что в любой момент будет загружена в
память только одна версия DLL-файла. Если две программы обращаются к одной и той же
библиотеке, то в памяти будет находиться только одна копия DLL-файла.
Примечание
Библиотеки DLL всегда динамические и создаются они с целью динамической загрузки
находящихся в них ресурсов. Но, не смотря на это, многие компиляторы позволяют
присоединять код DLL статически. В этом случае при компиляции программы код или
данные, находящиеся в DLL-файле, становятся неотъемлемой частью исполняемого
файла. Программа и библиотека становятся как единое целое. Это очень удобно, когда
библиотека небольшая или вам необходимо, чтобы программа состояла только из одного
запускного файла. Здесь динамическая загрузка не подходит, и надеяться на
существование библиотеки, на машине клиента нельзя. Такая ситуация может возникнуть,
когда вы хотите показать клиенту демонстрационный файл вашей программы и удобно
иметь только один запускной файл, а не множество библиотек.
Download