TN011. Использование MFC как часть библиотеки DLL
Эта заметка описывает обычной библиотеки DLL, которые позволяют использовать библиотеки MFC как часть библиотеки динамической компоновки Windows (DLL). Она высказывать, знакома с библиотекой DLL Windows и построения их. Дополнительные сведения о библиотеке DLL расширения MFC, с помощью которой можно создать расширения с библиотекой MFC, см. в разделе Версия библиотеки DLL MFC.
Интерфейсы DLL
Обычные библиотеки DLL, имеют интерфейсы между приложением и библиотекой DLL задается в похожих на C функций или явно экспортированных классов. Интерфейсы классов MFC нельзя экспортировать.
Если и DLL и приложение необходимо использовать MFC и, возможно, или вариант использования общая версия библиотек MFC или к статической привязке к копированию библиотек. Приложение и оба библиотеки DLL можно использовать одну из стандартных версий библиотеки MFC.
Обычная библиотека DLL имеет несколько преимуществ:
Приложение, использующее библиотеку DLL не обязательно использовать MFC и не должно быть приложением Visual C++.
С обычной библиотеки DLL, статически связанным с MFC, размер библиотеки DLL зависит только от подпрограммах MFC и среды выполнения C, используемые и связь.
С обычной библиотеки DLL, динамически связываемых с MFC, сбережения в памяти от использования общей версией MFC могут быть значительно. Однако следует распределять общие библиотеки DLL MFC DLL,<version> и <version>, Msvvcrt DLL с помощью библиотеки DLL.
Разработка библиотек DLL не реализованы как классы. При разработке библиотек DLL экспортирует только на интерфейсы требуется. В результате, если реализация изменяется, обычная библиотека DLL все еще является допустимым.
С обычной библиотеки DLL, статически связанным с MFC, если и библиотеки DLL и используют приложение MFC, то никаких проблем с приложением, которое требуется разную версию MFC DLL, или наоборот. Поскольку библиотека MFC статически связана в каждое DLL или EXE, не вопрос о том, какую версию имеется.
Ограничения API
Некоторые функции MFC не применяется к версии библиотек DLL или из-за технических ограничений или, поскольку эти службы обычно предоставляются приложением. В текущей версии MFC, единственная функция, не может применяться к CWinApp::SetDialogBkColor.
Построение библиотеки DLL
Когда компилировать обычной библиотеки DLL, статически связанным с MFC, и _USRDLL и _WINDLL должны быть определены. Код библиотеки DLL необходимо также компилировать со следующими переключателями компилятора:
/D_WINDLL означает компиляцию для библиотеки DLL
/D_USRDLL определяет построение обычной библиотеки DLL.
Необходимо определить эти символы и использовать эти переключатели компилятора при компилировать обычной библиотеки DLL, динамически связываемых с MFC. Кроме того, символ _AFXDLL должен быть определен и код библиотеки DLL необходимо компилировать с:
- /D_AFXDLL указывает, что при построении обычной библиотеки DLL, динамически связываемой с MFC
Интерфейсы (API) между приложением и библиотекой DLL должна быть явно экспортировать. Рекомендуется определены интерфейсы, чтобы быть низкой пропускной способностью и используется только интерфейсы C — если можно. Непосредственно интерфейсы C для поддержания проще, чем более сложные классы C C++.
Настройка API отдельно в заголовке, который может быть включен и файлами C C++. В разделе ScreenCap.h заголовок в расширенном примере MFC понятий DLLScreenCap для примера. Чтобы экспортировать функций, введите их в разделе EXPORTS файла определения модуля (.DEF), либо включить __declspec(dllexport) в определениях функций. Используйте __declspec(dllimport) для импорта эти функции в исполняемый файл клиента.
Необходимо добавить макрос AFX_MANAGE_STATE в начале всех экспортированных функций в обычной библиотеке DLL, динамически связываемых с MFC. Этот макрос задает текущее состояние модуля одну из библиотек DLL. Для использования этого макроса добавьте следующую строку кода в начало экспортированных функций из библиотеки DLL.
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
WinMain -> DllMain
Библиотека MFC определяет стандартную точку входа Win32 DllMain, инициализирует данный объект, производный CWinApp и в обычном приложении MFC. Разместите инициализацию библиотек DLL, в методе InitInstance и в обычном приложении MFC.
Обратите внимание, что механизм CWinApp::Run неприменим к библиотеке DLL, потому что главный цикл обработки сообщений находится в приложении. Если библиотека DLL отображает немодальные диалоговые окна или имеет главного фреймовое окно его, цикл обработки сообщений приложения главный должен вызвать библиотеку DLL экспортированную процедуры, которая вызывает CWinApp::PreTranslateMessage.
См. пример DLLScreenCap для использования этой функции.
Функция DllMain, MFC предоставляет вызывает метод CWinApp::ExitInstance класса, который является производным от CWinApp перед выгрузкой DLL.
Связывание библиотеки DLL
С обычной библиотеки DLL, статически связанным с MFC, необходимо связать библиотеки DLL с Nafxcwd.lib или Nafxcw.lib и с помощью трех выполнения C Libcmt.lib. Эти библиотеки предварительно подготовленный и могут быть установлены, указав их при запуске Visual C++ настраиваемых параметров.
Пример кода
См. пример программы MFC расширенный понятий DLLScreenCap полный пример. Ряд интересных вещей, которые следует принять во внимание в этом примере следующим образом:
Флажки компилятора библиотеки DLL, а два других приложений.
Линии связи и файлы .DEF для библиотеки DLL и другие элементы управления для приложения.
Приложение, использующее библиотеку DLL не должно находиться в C++.
Интерфейс между приложением и библиотекой DLL API, годно к использованию C или C++ экспортировано с DLLScreenCap.def.
В следующем примере показано API, определенный в обычной библиотеки DLL, статически скомпонована с MFC. В этом примере, объявление заключено в блок extern "C" { } для пользователей C C++. Это имеет несколько преимуществ. Во-первых, оно приводит к API библиотеки DLL можно было использовать в клиентские приложения, написанных не на C++. Во-вторых, он снижает нагрузку библиотеки DLL, поскольку корежить имени C++ не будет применяться к экспортированному имени. Наконец, оно облегчает явно добавить в файл .DEF (для экспортироваться порядковым номером) без беспокоиться о корежить имени.
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct TracerData
{
BOOL bEnabled;
UINT flags;
};
BOOL PromptTraceFlags(TracerData FAR* lpData);
#ifdef __cplusplus
}
#endif
Структуры, используемые API не являются производными от классов MFC и определены в заголовке API. Это упрощает интерфейса между приложением и библиотекой DLL и делает библиотеки DLL можно было использовать в для программ на языке C — программами.