Состояния модулей обычной библиотеки DLL MFC, динамически связанной с MFC
Возможность динамически связывать обычную библиотеку DLL MFC с библиотекой DLL MFC позволяет создавать сложные конфигурации. Например, обычная библиотека DLL MFC и исполняемый файл, который использует ее, могут динамически связываться с библиотекой DLL MFC и с любыми библиотеками DLL расширения MFC.
Такая конфигурация создает проблему в отношении глобальных данных MFC, таких как указатель на текущий объект CWinApp
и сопоставление дескрипторов.
До MFC версии 4.0 эти глобальные данные находились в самой библиотеке DLL MFC и были общими для всех модулей в процессе. Поскольку каждый процесс, использующий библиотеку DLL Win32, получает собственную копию данных библиотеки DLL, эта схема предоставляет простой способ отслеживания данных для каждого процесса. Кроме того, поскольку модель AFXDLL предполагает, что в процессе будет только один объект CWinApp
и только один набор сопоставлений дескрипторов, эти элементы можно было бы проконтролировать в самой библиотеке DLL MFC.
Но благодаря возможности динамически связывать обычную библиотеку DLL MFC с библиотекой DLL MFC, теперь можно иметь два или более объектов CWinApp
в процессе, а также два или более набора сопоставлений дескрипторов. Как MFC следит за тем, какие из них следует использовать?
Решение заключается в том, чтобы предоставить каждому модулю (приложению или обычной библиотеке DLL MFC) собственную копию этой глобальной информации о состоянии. Таким образом, вызов метода AfxGetApp в обычной библиотеке DLL MFC возвращает указатель на объект CWinApp
в библиотеке DLL, а не в исполняемом объекте. Эта копия для каждого модуля глобальных данных MFC называется состоянием модуля и описана в статье Техническое примечание 58 для MFC.
Процедура общего окна MFC автоматически переключается на правильное состояние модуля, поэтому вам не нужно беспокоиться о нем в обработчиках сообщений, реализованных в обычной библиотеке DLL MFC. Но когда исполняемый файл вызывает обычную библиотеку DLL MFC, необходимо явным образом задать для текущего состояния модуля значение библиотеки DLL. Для этого используйте макрос AFX_MANAGE_STATE в каждой функции, экспортированной из библиотеки DLL. Это можно сделать, добавив следующую строку кода в начало функций, экспортированных из библиотеки DLL:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))