共用方式為


DLLHUSK 範例:動態連結 MFC 程式庫

更新:2007 年 11 月

DLLHUSK 範例會以動態方式連結將 MFC 程式庫連結至應用程式並自訂共用相同類別庫程式碼的動態連結程式庫 (DLL),進而降低執行多個應用程式時所需的記憶體總數。

以動態方式連結至 MFC 也會提供其他可能的應用程式架構,這一部分的應用程式是在自訂的 DLL 中實作,且應用程式和自訂 DLL 都是共用 MFC DLL (Mfcxx.dll)。與應用程式一起共用架構功能的自訂 DLL,稱為 MFC 擴充 DLL。

安全性注意事項:

這個程式碼範例僅供概念說明之用,同時因為範例中的程式碼撰寫並沒有周全的顧及所有安全性問題,所以本範例不適用於實際執行的應用程式或網站中。如果使用者擅自將範例程式碼用於其他意圖而導致連帶事件或重大損害時,Microsoft 將不承擔任何責任。

若要取得範例和指示以便進行安裝:

  • 按一下 Visual Studio [說明] 功能表上的 [範例]。

    如需詳細資訊,請參閱尋找範例檔案

  • 最新版的完整範例清單可從 Visual Studio 2008 範例網頁 (英文) 取得。

  • 您也可以將範例置於電腦硬碟中。根據預設,範例和讀我檔案都會複製到 \Program Files\Visual Studio 9.0\Samples\ 下的資料夾中。對於所有的 Visual Studio Express 版,所有範例都可在線上找到。

建置和執行範例

若要建置並執行 DLLHUSK 範例

  1. 開啟 dllhusk.sln 方案。

  2. 在 [建置] 功能表上,按一下 [建置]。

  3. 在 [偵錯] 功能表上,按一下 [啟動但不偵錯]。

DLLHUSK 方案會同時建置 Dllhusk.exe 應用程式和應用程式以動態方式連結到的兩個 DLL (TESTDLL1.DLL 和 TESTDLL2.DLL)。在執行階段時,DLLHUSK 需要 MFCxx.DLL 或 MFCxxD.DLL。根據預設,這些 DLL 都已經安裝在 Windows 的系統目錄中。

DLLHUSK MFC 擴充 DLL

DLLHUSK 會示範具有類別匯出的 MFC 擴充。DLL (Testdll1.dll 和 Testdll2.dll) 中的 C++ 類別是使用 AFX_EXT_CLASS 巨集所匯出的。第一個 MFC 擴充 DLL (TESTDLL1),是一個在其中自訂 DLL 的所有 C++ 類別介面都只能由架構所存取,而無法由應用程式直接存取的 DLL。自訂 DLL 只會將 extern "C" 函式匯出至應用程式。自訂 DLL 不需要匯出衍生自架構類別之類別的函式。自訂 DLL 中所有從架構到衍生類別的呼叫,都是透過 C++ 虛擬函式 (Virtual Function) 機制所解析。

第二個 MFC 擴充 DLL (TESTDLL2),則是一個其中自訂 DLL 的某些 C++ 類別介面會被匯出並直接由應用程式所存取的 DLL。

Testdll1.dll

Testdll1.dll 可以同時為 TEXT 文件類型和 HELLO 文件類型提供 DLLHUSK 文件和檢視類別的實作。Dllhusk.exe 會實作 MDI 框架視窗類別,而架構則會實作多重文件介面 (MDI) 子視窗類別 (CMDIChildWnd)。兩種文件樣板物件都會在 CTextDoc、CMDIChildWndCEditView 之間,以及在 CDummyDoc、CMDIChildWnd 和 CHelloView 之間建立關聯。因此,DLLHUSK 說明架構能夠協調架構定所義物件之間的關係,雖然這些物件的類別都是在應用程式、自訂 (MFC 擴充) DLL 和架構的 Mfcxx.dll 中實作。

實際上,TESTDLL1 會呼叫應用程式物件的 AddDocTemplate 成員函式兩次來登錄兩種文件樣板物件。它會在 TESTDLL1 的 InitTestDLL1 函式 (此函式是 TESTDLL1 匯出的唯一函式) 實作中以這種方式進行。這個函式是以 extern "C" 宣告,所以 DLLHUSK 應用程式能夠將它當做獨立 C 函式來呼叫。

Testdll1.h 標頭檔 (由 Dllhusk.cpp 加入為 #include) 不只包含 InitTestDLL1, 的宣告,也包含了 TESTDLL1 的類別宣告。Dllhusk.cpp 只會直接參考 InitTestDLL1 函式。然而,DLLHUSK 會間接使用在 Testdll1.dll 中實作的文件和檢視類別。

Testdll2.dll

Testdll2.dll 會提供 DLLHUSK 的 CListOutputFrame 類別的實作。當使用者藉由使用快速鍵功能表選擇診斷的命令時,應用程式會建立 CListOutputFrame 物件,然後藉由呼叫 CListOutputFrame::AddString 來將診斷訊息傳送至 List Output window 視窗。

CListOutputFrame 的所有 Public 成員函式都會匯出至 Testdll2.def 檔案。匯出並不只包含 AddString,還包括公用 (Public) 的 CListOutputFrame 建構函式和解構函式。

實作能夠匯出類別成員函式的 MFC 擴充 DLL 比實作只能匯出 C 函式的 DLL 還要困難。這是因為您必須要手動將 C++ 名稱裝飾函式匯出項目加入至 DLL 的 .def 檔案中。在技術提示 33 中有詳細說明執行此步驟的技術。

其他的 DLLHUSK 功能

DLLHUSK 也說明了:

  • 將單一應用程式的資源劃分為多個可以在 Visual C++ 資源編輯器中進行編輯的 .rc 檔案。

  • 使用兩個全域診斷函式 AfxDoForAllClassesAfxDoForAllObjects

  • 列舉 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++ 精靈、程式庫以及編譯器方面的變更,不過還是可以示範如何完成您要進行的工作。

請參閱

其他資源

MFC 範例