Использование динамических библиотек

Приложения, работающие в ОС Windows состоят из исполняемых файлов и динамических библиотек (Dynamic Link Library, DLL) [4].

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

В динамических библиотеках можно определить 2 типа функций: внешние (экспортируемые) и внутренние. Экспортируемые функции могут вызываться как из DLL в которой они описаны, так и из других модулей. Внутренние функции могут использоваться только в том модуле, в котором они описаны.

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

Набор API-функций, с помощью которых пользовательское приложение взаимодействует с операционной системой, реализован как набор динамических библиотек, поэтому все приложения Windows используют динамические библиотеки.

Динамическое связывание позволяет включать в модули только информацию об экспортируемой в момент загрузки или во время выполнения программы функции DLL. Существует 2 метода вызова функции из DLL.

1. Динамическое связывание во время загрузки (Load-Time Dynamic Linking). В этом случае модуль осуществляет явный вызов экспортируемой функции так, будто она является его локальной функцией. Этот способ требует наличия библиотеки импорта, связанной с DLL содержащей экспортируемые функции, которая обеспечивает ОС информацией, необходимой для загрузки этой DLL и расположением экспортируемых функций внутри DLL.

2. Динамическое связывание во время выполнения программы (Run-Time Dynamic Linking). В этом случае, вызывающее приложение должно использовать специальные API-функции для загрузки DLL, выгрузки DLL и получения адреса экспортируемой функции. Самостоятельное получение адреса экспортируемой функции приводит к тому, что нет необходимости создавать библиотеку импорта.

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

Для каждой загруженной DLL ОС создает счетчик обращений. Когда процесс загружает DLL, счетчик обращений увеличивается на 1, когда процесс завершается или когда счетчик обращений становится равным 0 (только для динамического связывания во время выполнения программы) - динамическая библиотека выгружается из виртуального адресного пространства процесса.

Как и другая функция, экспортируемая DLL функция выполняется в контексте того потока, который ее вызвал.

Как уже говорилось, динамические библиотеки представляют собой исполняемые модули, содержащие функции и данные, т.е. фактически - динамические библиотеки не отличаются от обычных программ. Разница заключается лишь в том, что функции, определенные в динамических библиотеках могут вызываться другими программными модулями. Многие среды разработки предоставляют шаблон для создания динамической библиотеки.

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

Для выделения экспортируемых функций, в тексте программы DLL за процедурой, вызываемой из другого модуля, необходимо указать ключевое слово EXPORT (если предполагается транслировать этот модуль с помощью пакета MASM) или объявить эту процедуру как PUBLIC (если предполагается транслировать этот модуль с помощью пакета TASM). Если же используется какая-либо среда разработки, то как правило, создание DLL осуществляется на основе шаблона.

Использование динамически связываемых во время загрузки DLL можно наблюдать в приложении А на примере API-функций.

Для использования динамически связываемых во время выполнения DLL используются следующие API-функции:

LoadLibrary - для загрузки DLL в виртуальное пространство вызывающего процесса и получения описателя (дескриптора) данной библиотеки;

GetProcAddress - для получения адреса процедуры, находящейся в динамической библотеке.

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: