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 - &gt; 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 можно было использовать написаннаяыми на программами.

См. также

Другие ресурсы

Технические замечания по номеру

Технические замечания по категориям