Обычные библиотеки DLL, динамически связываемые с MFC
Обычная библиотека DLL, динамически связываемая с MFC — это библиотека DLL, внутренне использующая MFC. Экспортируемые функции этой библиотеки могут вызываться исполняемыми приложения MFC и другими приложениями. Как понятно из названия, этот вид библиотек DLL построен с использованием версии библиотеки динамической компоновки MFC (также называемой общей версией MFC). Функции экспортируются из обычной библиотеки DLL, используя, как правило, стандартный интерфейс языка C.
Чтобы установить для текущего состояния модуля одну из библиотек DLL, необходимо добавить макрос AFX_MANAGE_STATE в начало всех экспортируемых функций в обычных библиотеках DLL, которые динамически связываются с MFC. Для этого следует добавить следующий код в начало функций, экспортируемых из библиотеки DLL:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
Обычная библиотека DLL, динамически связываемая с MFC, обладает следующими возможностями.
Это новый тип библиотеки DLL, впервые представленный в Visual C++ 4.0.
Клиентский исполняемый модуль может быть создан на любом языке, поддерживающим использование библиотек DLL (C, C++, Pascal, Visual Basic и т. д.); ему не обязательно быть приложением MFC.
В отличие от статически связываемых обычных DLL, этот вид библиотек DLL динамически связывается с DLL-библиотекой MFC (также называемой общей DLL-библиотекой MFC).
С этим типом библиотеки DLL связана та же библиотека импорта MFC, которая используется для DLL-библиотек расширения или приложений, использующих DLL-библиотеки MFC: MFCxx(D).lib.
Для обычной библиотеки DLL, динамически связываемой с MFC, применяются следующие требования.
Эти библиотеки DLL компилируются с заданным макросом _AFXDLL так же, как и исполняемое приложение, динамически связываемое с библиотекой DLL MFC. Также задается макрос _USRDLL, как для обычной библиотеки DLL, статически связываемой с MFC.
Такой тип DLL должен создавать экземпляр, производный от класса CWinApp.
Этот тип DLL использует функцию DllMain, предоставляемую MFC. Код инициализации DLL необходимо размещать в функции-члене InitInstance, а код завершения — в функции ExitInstance, как и в обычном приложении MFC.
Так как такой тип DLL использует версию библиотеки динамической компоновки MFC, необходимо напрямую установить для текущего состояния модуля одну из библиотек DLL. Для этого используйте макрос AFX_MANAGE_STATE в начале каждой экспортируемой из DLL функции.
Стандартные библиотеки DLL, как и приложения MFC, должны содержать класс, производный от CWinApp, и один объект этого класса. Однако объект CWinApp библиотеки DLL не имеет цикла обработки сообщений CWinApp приложения.
Обратите внимание, что механизм CWinApp::Run неприменим к библиотеке DLL, потому что главный цикл обработки сообщений находится в приложении. Если библиотека DLL вызывает немодальное диалоговое окно или в ней присутствует собственное главное окно, основной конвейер сообщений приложения должен вызывать экспортируемую из DLL процедуру, вызывающую функцию CWinApp::PreTranslateMessage.
Разместите инициализацию для отдельной библиотеки DLL в функции-члене CWinApp::InitInstance, как в обычном приложении MFC. Функция-член CWinApp::ExitInstance производного класса CWinApp вызывается из функции DllMain, предоставляемой MFC, перед выгрузкой DLL.
Вместе со создаваемым приложением необходимо распространять общие библиотеки DLL MFCx0.dll и Msvcr*0.dll (или аналогичные файлы).
Библиотека DLL, динамически связываемая с MFC, не может одновременно статически связываться с MFC. Приложения связываются с обычными DLL, динамически связываемыми с MFC, как и с любыми другими DLL.
Символы экспортируются из обычной библиотеки DLL, используя, как правило, стандартный интерфейс языка C. Объявление функции, экспортируемой из обычной DLL, выглядит приблизительно следующим образом:
extern "C" __declspec(dllexport) MyExportedFunction( );
Вся выделенная библиотекой DLL память должна использоваться только внутри этой DLL. Библиотека DLL не должна передавать или получать из вызывающего исполняемого модуля следующие элементы:
указатели на объекты MFC;
указатели памяти, выделенной библиотекой MFC.
Если все-таки требуется передать подобные элементы или если необходимо передать объекты, производные от MFC, из вызываемого исполняемого файла в DLL и наоборот, то следует построить DLL-библиотеку расширения.
Передавать указатели памяти, выделенной библиотеками времени выполнения языка C, между приложением и библиотекой DLL безопасно только в том случае, если выполняется копирование данных. Нельзя удалять или изменять размеры этих указателей, или же использовать их без копирования памяти.
При построении обычной DLL, динамически связываемой с MFC, необходимо использовать макрос AFX_MANAGE_STATE для корректного переключения состояния модуля MFC. Для этого следует добавить следующий код в начало функций, экспортируемых из библиотеки DLL:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
Макрос AFX_MANAGE_STATE не следует использовать в обычных DLL, которые статически связываются с MFC, или в DLL-библиотеках расширения. Дополнительные сведения см. в разделе Управление данными состояния модулей MFC.
Пример создания, построения и использования обычной библиотеки DLL см. в разделе DLLScreenCap. Дополнительные сведения об обычных библиотеках DLL, динамически связываемых с MFC, см. в разделе "Преобразование DLLScreenCap для динамического связывания с DLL-библиотекой MFC" в описании примера.
Задачи, которые необходимо выполнить
Дополнительные сведения
Состояния модулей обычной библиотеки DLL, динамически связываемой с MFC
Использование библиотек DLL расширения баз данных, OLE и сокетов в обычных библиотеках DLL