Образец DLLHUSK: динамическое связывание библиотеки MFC
Обновлен: Ноябрь 2007
В образце DLLHUSK выполняется динамическое связывание библиотеки MFC с приложениями и пользовательскими библиотеками DLL. При этом код библиотеки классов используется многократно, что позволяет сократить общий объем памяти, необходимой для выполнения нескольких приложений.
Динамическое связывание с библиотекой MFC также позволяет применять другую архитектуру для создания приложений, когда часть приложения реализуется в пользовательской библиотеке DLL, а библиотека DLL MFC (Mfcxx.dll) совместно используется приложением и пользовательской библиотекой DLL. Пользовательская библиотека DLL, которая использует функции платформы совместно с приложением, называется библиотекой расширения MFC.
Примечание о безопасности. |
---|
Этот образец кода служит для демонстрации основных принципов и не предназначен для использования в приложениях или на веб-узлах, поскольку не может считаться примером наиболее безопасного кода. Корпорация Майкрософт не несет ответственности за случайные или косвенные убытки в случае использования образца кода не по назначению. |
Чтобы получить образцы и инструкции по их установке, выполните следующие действия.
В меню Справка среды Visual Studio выберите пункт Примеры.
Дополнительные сведения см. в разделе Поиск файлов примеров.
Самая последняя версия и полный список образцов доступны в Интернете на странице образцов Visual Studio 2008.
Кроме того, образцы находятся на жестком диске компьютера. По умолчанию образцы кода и файл Readme копируются в папку, находящуюся в папке \Program Files\Visual Studio 9.0\Samples\. Все образцы кода для экспресс-выпусков Visual Studio находятся в Интернете.
Построение и запуск образца
Построение и запуск образца DLLHUSK
Откройте решение dllhusk.sln.
В меню Построение выберите команду Построить.
В меню Отладка выберите пункт Запуск без отладки.
В решении DLLHUSK выполняется построение приложения Dllhusk.exe и двух библиотек DLL (TESTDLL1.DLL и TESTDLL2.DLL), с которыми приложение динамически связывается. Во время выполнения DLLHUSK необходима библиотека MFCxx.DLL или MFCxxD.DLL. Эти библиотеки по умолчанию устанавливаются в системном каталоге Windows.
Библиотеки расширения MFC DLLHUSK
В DLLHUSK показаны библиотеки расширения MFC с экспортом классов. Классы C++ в библиотеках (Testdll1.dll и Testdll2.dll) экспортируются с помощью макроса AFX_EXT_CLASS. В первой библиотеке расширения MFC (TESTDLL1) доступ ко всем интерфейсам классов C++ из пользовательской библиотеки DLL выполняется только со стороны платформы, а приложение не получает непосредственный доступ к интерфейсам. Пользовательская библиотека DLL экспортирует в приложение только функции extern "C". Пользовательская библиотека DLL не должна экспортировать функции классов, производных от классов платформы. Все вызовы из платформы в производные классы разрешаются в пользовательской библиотеке посредством механизма виртуальных функций C++.
Во второй библиотеке расширения MFC (TESTDLL2) некоторые интерфейсы классов C++ из пользовательской библиотеки DLL экспортируются в приложение, и приложение выполняет к ним непосредственный доступ.
Testdll1.dll
В файле Testdll1.dll реализованы классы документов и представлений DLLHUSK для обоих типов документов — тип TEXT и тип HELLO. В файле Dllhusk.exe реализован класс дочернего фрейма окна интерфейса MDI, а платформа реализует класс дочернего окна интерфейса MDI (CMDIChildWnd). Два объекта шаблона документа устанавливают связи между CTextDoc, CMDIChildWnd и CEditView, а также между CDummyDoc, CMDIChildWnd и CHelloView. Таким образом, в образце DLLHUSK показано, как платформа выполняет согласование связей между объектами, определенными в платформе, даже когда классы для этих объектов реализованы в приложении, в пользовательской библиотеке (расширении MFC) и в файле платформы Mfcxx.dll.
Библиотека TESTDLL1 фактически выполняет двукратный вызов функции-члена AddDocTemplate объекта приложения, чтобы зарегистрировать два объекта шаблона документа. Это выполняется в реализации функции InitTestDLL1 TESTDLL1, которая является единственной функцией, экспортируемой библиотекой TESTDLL1. Эта функция объявляется с ключевым словом extern "C", чтобы приложение DLLHUSK могло вызывать ее в качестве изолированной функции C.
В файл заголовка Testdll1.h (который добавляется директивой #include в файле Dllhusk.cpp) входит не только объявление InitTestDLL1, но также объявления классов TESTDLL1. Файл Dllhusk.cpp непосредственно ссылается только на функцию InitTestDLL1. Однако приложение DLLHUSK косвенным образом использует классы документов и представлений, реализованные в библиотеке Testdll1.dll.
Testdll2.dll
В файле Testdll2.dll реализован класс CListOutputFrame DLLHUSK. Когда пользователь выбирает команду диагностики из контекстного меню, приложение создает объект CListOutputFrame, а затем отправляет диагностические сообщения в окно List Output, вызывая метод CListOutputFrame::AddString.
Все открытые функции-члены класса CListOutputFrame экспортируются в файл Testdll2.def. Экспортируется не только метод AddString, но и открытые конструктор и деструктор класса CListOutputFrame.
Реализовать библиотеку расширения MFC, которая экспортирует функции-члены класса, сложнее, чем библиотеку, которая экспортирует только функции C. Это обусловлено, в частности, тем, что необходимо вручную добавлять экспортируемые функции с декорированием имен C++ в DEF-файл библиотеки. Эта методика подробно описана в статье Технические заметки 33.
Дополнительные возможности DLLHUSK
В образец DLLHUSK также показаны следующие возможности:
Разделение ресурсов для одного приложения на несколько RC-файлов, которые можно редактировать в редакторе ресурсов Visual C++.
Использование двух глобальных диагностических функций — AfxDoForAllClasses и AfxDoForAllObjects.
Перечисление объектов CDynLinkLibrary.
Ключевые слова
В этом образце показаны следующие ключевые слова:
AfxDoForAllClasses; AfxDoForAllObjects; AfxGetApp; AfxGetResourceHandle; AfxMessageBox; AfxSetResourceHandle; AfxThrowMemoryException; CCmdUI::SetCheck; CColorDialog::DoModal; CColorDialog::GetColor; CDC::DrawText; CDC::SetBkColor; CDC::SetTextColor; CDialogBar::Create; CDocTemplate::GetDocString; CEditView::SerializeRaw; CFrameWnd::LoadFrame; CListBox::AddString; CListBox::Create; CListBox::GetCount; CListBox::GetText; CListBox::GetTextLen; CListBox::ResetContent; CListBox::SetCurSel; CMDIChildWnd::Create; CMenu::GetSubMenu; CMenu::LoadMenu; CMenu::TrackPopupMenu; CObject::AssertValid; CObject::Dump; CObject::Serialize; CStatusBar::Create; CStatusBar::SetIndicators; CToolBar::Create; CToolBar::LoadBitmap; CToolBar::SetButtons; CView::OnDraw; CWinApp::AddDocTemplate; CWinApp::InitInstance; CWinApp::LoadStdProfileSettings; CWinApp::OnFileNew; CWinApp::OpenDocumentFile; CWnd::GetClientRect; CWnd::GetCurrentMessage; CWnd::GetFont; CWnd::Invalidate; CWnd::OnCreate; CWnd::OnNcRButtonDown; CWnd::OpenClipboard; CWnd::SetFont; CWnd::ShowWindow; CWnd::UpdateWindow; CloseClipboard; EmptyClipboard; GetModuleFileName; GetSysColor; GlobalAlloc; GlobalLock; LOWORD; RGB; SetClipboardData; lstrlen; wsprintf
Примечание. |
---|
Некоторые образцы, включая данный, не модифицировались с учетом изменений в мастерах, библиотеках и компиляторе Visual C++, однако по-прежнему демонстрируют выполнение требуемой задачи. |