TN011. Использование MFC как часть библиотеки DLL
это примечание описывает обычные библиотеки dll mfc, которые позволяют использовать библиотеку mfc в составе Windows библиотеки динамической компоновки (DLL). предполагается, что вы знакомы с Windows библиотеками dll и как их создавать. Дополнительные сведения о библиотеках DLL расширения MFC, в которых можно создавать расширения для библиотеки MFC, см. в статье DLL-версия MFC.
Интерфейсы DLL
обычные библиотеки DLL MFC предполагают, что интерфейсы между приложением и библиотекой DLL указываются в функциях, похожих на C, или в явно экспортированных классах. Не удается экспортировать интерфейсы классов MFC.
Если и библиотека DLL, и приложение хотят использовать MFC, то оба варианта могут либо использовать общую версию библиотек MFC, либо статически связать их с копией библиотек. Приложение и библиотека DLL могут использовать одну из стандартных версий библиотеки MFC.
обычные библиотеки DLL MFC имеют несколько преимуществ.
Приложение, использующее библиотеку DLL, не должно использовать MFC и не обязательно должно быть приложением Visual C++.
С помощью регулярных библиотек MFC, которые статически связываются с MFC, размер библиотеки DLL зависит только от используемых и связанных подпрограмм среды выполнения MFC и C.
Благодаря обычным библиотекам DLL MFC, динамически связываемым с MFC, экономия в памяти от использования общей версии MFC может быть значительной. Однако необходимо распространять общие библиотеки DLL,версию>.dll MFC < иверсию> мсввкрт <.dll с библиотекой DLL.
Структура DLL не зависит от реализации классов. Структура библиотек DLL экспортирует только необходимые API-интерфейсы. В результате, если реализация изменяется, стандартные библиотеки DLL MFC остаются действительными.
С помощью регулярных библиотек MFC, которые статически связываются с MFC, если и библиотека DLL, и приложение используют MFC, нет проблем с приложением, которым требуется другая версия MFC, чем у библиотеки DLL, или наоборот. Так как библиотека MFC связана статически с каждой библиотекой DLL или EXE, нет вопросов о том, какая версия имеется.
Ограничения API
Некоторые функции MFC не применяются к версии библиотеки DLL из-за технических ограничений или из-за того, что эти службы обычно предоставляются приложением. В текущей версии MFC единственной неприменимой функцией является CWinApp::SetDialogBkColor
.
Создание библиотеки DLL
При компиляции регулярных библиотек DLL MFC, которые статически связываются с MFC, символы _USRDLL
и _WINDLL
должны быть определены. Код библиотеки DLL также должен быть скомпилирован с помощью следующих параметров компилятора:
/D_WINDLL означает, что компиляция предназначена для библиотеки DLL
/D_USRDLL указывает, что вы создаете обычную БИБЛИОТЕКУ DLL MFC
Необходимо также определить эти символы и использовать эти параметры компилятора при компиляции регулярных библиотек DLL MFC, которые динамически связываются с MFC. Кроме того, символ _AFXDLL
должен быть определен, и код DLL должен быть скомпилирован с помощью:
- /D_AFXDLL указывает, что создается обычная библиотека DLL MFC, которая динамически связывается с MFC.
Интерфейсы (API) между приложением и библиотекой DLL должны быть экспортированы явным образом. Рекомендуется определить интерфейсы с низкой пропускной способностью и использовать только интерфейсы C, если это возможно. Прямые интерфейсы C проще в обслуживании, чем более сложные классы C++.
Разместите API в отдельном заголовке, который можно включать в файлы C и C++. Пример см. в заголовке снимке экрана. h в образце примера " дополнительные понятия MFC". Чтобы экспортировать функции, введите их в EXPORTS
раздел файла определения модуля (. DEF) или включить __declspec(dllexport)
в определения функций. Используйте __declspec(dllimport)
для импорта этих функций в исполняемый файл клиента.
Необходимо добавить AFX_MANAGE_STATE макрос в начало всех экспортированных функций в обычных библиотеках DLL MFC, которые динамически связываются с MFC. Этот макрос задает текущее состояние модуля для библиотеки DLL. Чтобы использовать этот макрос, добавьте следующую строку кода в начало функций, экспортированных из библиотеки DLL:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
WinMain- > DllMain
Библиотека MFC определяет стандартную точку входа Win32 DllMain
, которая инициализирует производный объект CWinApp как в обычном приложении MFC. Поместите всю инициализацию библиотеки DLL в метод InitInstance , как в обычном приложении MFC.
Обратите внимание, что механизм CWinApp:: Run не применяется к библиотеке DLL, так как приложение владеет основным конвейером сообщений. Если в библиотеке DLL отображаются немодальные диалоговые окна или имеется главное окно фрейма, то основной конвейер сообщений приложения должен вызвать подпрограммы, экспортируемые из библиотеки DLL, вызывающие CWinApp::P ретранслатемессаже.
См. пример DLLScreenCap для использования этой функции.
DllMain
Функция, предоставляемая библиотекой MFC, будет вызывать метод CWinApp:: ExitInstance класса, производного от CWinApp
, перед выгрузкой библиотеки DLL.
Связывание библиотеки DLL
С помощью регулярных библиотек MFC, которые статически связываются с MFC, необходимо связать библиотеку DLL с Нафксквд. lib или Нафкскв. lib и версией среды выполнения C с именем LIBCMT. lib. Эти библиотеки предварительно созданы и могут быть установлены путем указания их при запуске программы установки Visual C++.
Пример кода
Полный пример см. в образце программы MFC с примерами программ для опытных концепций. В этом примере обратите внимание на несколько интересных моментов.
Флаги компилятора библиотеки DLL и приложения отличаются.
Линии связи и. DEF-файлы для библиотеки DLL и для приложения различаются.
Приложение, использующее библиотеку DLL, не обязательно должно находиться в C++.
Интерфейс между приложением и библиотекой DLL — это API, который может использоваться C или C++ и экспортирован с помощью DLLScreenCap. def.
В следующем примере показан API, определенный в обычной библиотеке DLL MFC, которая статически связывается с MFC. В этом примере объявление заключено в extern "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.
См. также раздел
Технические примечания по номеру
Технические примечания по категориям