40. Динамические библиотеки (dll).
DLL (Dynamic-Link Library) - динамически загружаемые библиотеки. Существуют два типа DLL
Обычные DLL MFC - библиотеки (MFC regular DLL)
Расширенные DLL MFC - библиотеки (MFC extension DLL)
Динамически подключаемая библиотека - это специального вида исполняемый файл с расширением .dll, используемый для хранения классов, функций и ресурсов отдельно от исполняемого файла.
Существует и другой способ хранения скомпилированного кода отдельно от исходного кода приложения - в библиотечных файлах с расширением .lib. Этот код включается в приложение линковщиком в процессе создания приложения. Такой процесс называется статическим связыванием. Код библиотеки хранится в исполняемом файле приложения. И если библиотеку использует несколько приложений, экземпляр кода будет включен в исполнимый файл каждого приложения.
Использование DLL обеспечивает динамическое связывание, когда код библиотеки загружается в память и присоединяется к приложению при его запуске на выполнение. Приложение, запущенное на выполнение, называетсяпроцессом. Если одновременно выполняются несколько процессов, то каждый процесс может загружать из DLL и присоединять к себе нужную функцию или даже все процессы одну и ту же функцию одновременно.
Применение DLL позволяет реконструировать и сопровождать функцию (или класс) только в одном экземпляре и все внесенные в нее изменения будут немедленно учтены любыми использующими ее приложениями без предварительной их перекомпиляции. Можно считать, что DLL является источником кода, а все упакованные в нее функции и классы - экспортируемыми функциями и классами.
Создание программ с использованием объектно-ориентированного подхода - это практика программирования, в основу которой положены те же принципы, что используются при любом техническом проектировании
Достоинства DLL
Поскольку в DLL можно разместить функции, к которым обращаются многие приложения, то уменьшаются размеры исполняемых файлов приложений на этапе компиляции
Если интерфейс DLL не изменяется, то ее можно заменить более новой, причем сами приложения обновлять не придется
При надлежащем выборе типа DLL ее можно использовать в приложениях, написанных на других языках программирования для Windows
Динамически загружаемые библиотеки - это файлы с заранее откомпилированными кодами функций или классов, которые могут использоваться другими приложениями на этапе выполнения. Функция или класс добавляются в специальную таблицу, являющуюся неотъемлемой частью DLL. В таблице указывается местоположение всех функций и классов, содержащихся в DLL, что обеспечивает быстрый их поиск и вызов исполняемым внешним приложением при его загрузке в память.
Приложение может вызывать код из DLL двумя способами:
По таблице определяется местоположение нужной функции, создается указатель на найденную функцию, с помощью указателя вызывается сама функция
Приложение линкуется с обычным библиотечным LIB-файлом, в котором содержатся фиктивные модули программного кода (заглушки). При запуске приложения фиктивный псевдокод замещается реальным кодом из DLL
Заглушка - это псевдофункция, у которой имя и список аргументов совпадают с именем и списком аргументов реальной функции. Внутри функции-заглушки имеется незначительное количество кода, вызывающего реальную функцию из DLL, причем реальной функции при вызове передаются все те аргументы, которые были переданы заглушке. В этом смысле функции DLL можно рассматривать как часть кода приложения, а не как отдельный файл.
Второй способ значительно проще. Библиотечный LIB-файл при компиляции DLL создается автоматически. Для его создания не приходится предпринимать каких-либо особых действий. При использовании LIB-файлов все используемые в приложении DLL загружаются в память в момент запуска приложения и если некоторые из них отсутствуют, то Windows автоматически предупреждает об этом и приложение не выполняется.
Когда используется первый способ, разработчику приложения необходимо самостоятельно организовывать загрузку DLL в память и обрабатывать все ошибочные ситуации при отсутствии нужных DLL.
DLL создаются с помощью оболочки Visual Studio специальным мастером DLL Wizard.
MFC extension DLL
MFC extension DLL - это динамически загружаемые библиотеки, расширяющие библиотеку базовых классов MFC. Такой тип DLL легче всего создавать и кодировать. Чтобы сделать класс экспортируемым DLL, нужно при его объявлении указать макрос AFX_EXT_CLASS примерно так
class AFX_EXT_CLASS MyClass // Объявление класса
{
..................
};
Далее в приложении, использующем класс, достаточно будет включить этот макрос, и при запуске приложения будет импортирование из DLL нужный класс.
Одним из недостатков MFC extension DLL является то, что их нельзя использовать в программах, написанных на других языках программирования или в программахC++, компиляторы которых не поддерживают MFC. Но компиляторы фирмы Borland и Symantec поддерживают MFC extension DLL.
MFC regular DLL
MFC regular DLL - это обычные динамически загружаемые библиотеки. Этот тип DLL поддерживает стандартные функции, а не классы, поэтому планировать их приходится несколько тщательнее, чем MFC extension DLL. Внутри самой DLL классы можно использовать, но вызов кода внешним приложением нужно организовать через функцию.
Для обеспечения возможности экспорта функции библиотекой следует эту функцию объявить экспортируемой по такому синтаксису
extern "C" тип_возвращаемого_значения PASCAL EXPORT объявление_функции
Необходимо включить все эти дополнительные слова как в заголовочный файл прототипа функции, так и в исходный код ее реализации.
Выражение extern "C" объявляет, что это вызов стандартной функции C, поэтому корректировщик имен C++ не должен корректировать имя функции
Ключевое слово PASCAL сообщает компилятору, что все параметры функции передаются в порядке, принятом в языке PASCAL, т.е. параметры в стеке размещаются в порядке, обратном обычному
Ключевое слово EXPORT информирует компилятор о том, что эта функция будет экспортироваться динамически загружаемой библиотекой во внешние приложения
Для создания DLL применяется специальный тип проекта оболочки Visual Studio. Чтобы сделать функции экспортируемыми DLL, следует добавить их имена в файл определений DEF.lib этого проекта. Файл DEF.lib представляет собой библиотечный (т.е. с расширением LIB) файл заглушек и таблицу экспортируемых функций, содержащихся в DLL. В него включается имя DLL, ее краткое описание и имена всех экспортируемых библиотекой функций. Файл DEF проекта DLLавтоматически создается мастером "DLL Wizard" и имеет определенный формат. Формат файла изменять нельзя, в него можно только добавлять имена экспортируемых функций.
Примерный вид файла определений DEF.lib
LIBRARY "mydll"
DESCRIPTION 'mydll Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
MyFun1
MyFun2
MyFun3
Если в MFC regular DLL используются классы из MFC, то первой строчкой тела всех экспортируемых функций должен быть вызов макроса AFX_MANAGE_STATE. Это диктуется необходимостью обеспечить многопоточную поддержку в функциях, благодаря которой можно вызывать функции класса одновременно несколькими потоками процесса. Макрос AFX_MANAGE_STATE имеет единственный аргумент - указатель на структуру AFX_MANAGE_STATE, который можно получить в результате вызова функции AfxGetStaticModuleState(). Типичная экспортируемая функция, использующая библиотеку MFC, имеет следующий вид
extern "C" void PASCAL EXPORT MyFun(список_аргументов)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Далее идет обычное тело функции
.....................
}
При проектировании функций для DLL нужно соблюдать правила:
Поскольку некоторые функции могут одновременно вызываться несколькими потоками процесса, то следует в них предусмотреть поддержку многопоточности
Функции не должны обрабатывать глобальные переменные, а все необходимые значения для локальных переменных должны передаваться функциям через аргументы. Если же все-таки необходимо обрабатывать глобальные переменные функциями, то следует предусмотреть для них защиту с помощью механизма синхронизации потоков
- 25. Понятие объекта и класса.
- Определение методов класса
- Переопределение операций
- Подписи методов и необязательные аргументы
- Запись классов
- 26. Скрытие данных и общий интерфейс.
- 27. Конструкторы и деструкторы Инициализация объектов класса: конструкторы
- Основное назначение конструкторов - инициализация объектов.
- Использование конструкторов с аргументами по умолчанию
- Если параметры не передаются конструктору, в определении объекта не нужно включать пустые круглые скобки.
- Использование деструкторов
- Когда вызываются конструкторы и деструкторы.
- 28. Перегрузка классов.
- Перегрузка операторов плюс и минус
- Второй пример
- Операторы, которые Вbl he можете перегрузить
- 29. Дружественные классы.
- 30. Наследование.
- Внутреннее и защищенное наследование
- Виртуальное наследование
- 31. Множественное наследование.
- 32. Полиморфизм.
- 33. Виртуальная функция.
- 34. Передача данных по умолчанию.
- 39. Создание и уничтожение динамических объектов.
- 40. Динамические библиотеки (dll).