TN011: Использование MFC как часть библиотеки DLL
Эта заметка описывает обычные библиотеки DLL, которые позволяют использовать библиотеки MFC windows как часть библиотеки динамической компоновки (DLL).Она предполагает, что читатель знаком с библиотекой DLL окон и о способах построения этих последовательностей.Дополнительные сведения о библиотеках 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 и Msvvcrt <версия>.dll, вместе с библиотекой DLL.
Построение библиотеки DLL независимый как классы реализованы.Ваша построение библиотеки DLL экспортирует только к API требуется.В результате, если реализация изменяется, обычные библиотеки 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++.
Поместите собственные 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.Эти библиотеки pre-построены и могут быть установленны, указав их при запуске программы установки Visual C++.
Пример кода
См. пример программы MFC для демонстрации Основных понятий дополнительно DLLScreenCap полный код примера.Ряд интересных вещей, который необходимо отметить в этом образце следующим образом:
Флаги компилятора DLL, то из приложений различны.
Линии связи и def-файлы для библиотеки DLL, а для приложений различны.
Приложение, использующее библиотеку DLL не должен находиться в C++.
Интерфейс между приложением и библиотекой DLL API, который будет использовать c или C++ и экспортированно с DLLScreenCap.def.
Следующий пример демонстрирует API, указанное в обычной библиотеке DLL, статически скомпонована с MFC.В этом примере объявление заключен в блок extern "C" { } для пользователей C++.Это имеет несколько преимуществ.Во-первых, она выполняет работу API библиотеки DLL можно было использовать клиентскими приложениями non-C++.Во-вторых, снижает издержки библиотеки DLL, поскольку mangling имени C++ не будет применяться к экспортированному имени.Наконец, он облегчает явно добавить в файл DEF (для экспорта порядковым номером), не беспокоиться о mangling имени.
#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 можно было использовать написаннаяыми на программами.