TN011: 使用 MFC DLL 的一部分
這張便箋描述標準 dll 裡,這可讓您使用 MFC 程式庫做為 Windows 動態連結程式庫 (DLL) 的一部分。 它假設您已熟悉 Windows Dll,以及如何建立它們。 MFC 擴充 Dll 的相關資訊,您可以建立與擴充 MFC 程式庫,請參閱的 MFC DLL 版本。
DLL 介面
標準 dll 裡假設類似 c 函式或明確地匯出的類別中所指定的應用程式和 DLL 之間的介面。 無法匯出 MFC 類別介面。
如果想使用 MFC DLL,並應用程式,兩者都可以使用共用的 MFC 程式庫版本或是以靜態方式連結到一份文件庫。 應用程式和 DLL 都可能使用其中一個標準的 MFC 程式庫版本。
標準 dll 裡有幾個優點:
使用 DLL 的應用程式並不一定要使用 MFC,而且沒有以 Visual C++ 應用程式。
以靜態方式連結至 MFC 的標準 dll 裡,使用 DLL 的大小只會依賴的 MFC 和 c 執行階段常式的使用與連結。
使用動態連結至 MFC 的標準 dll 裡,所節省的記憶體,無法使用共用的 MFC 版本可能更為顯著。 不過,您必須同時散發共用的 Mfc Dll,<version>.dll 和 Msvvcrt<version>.dll,與您的 DLL。
DLL 設計無關的類別實作的方式。 您的 DLL 設計將匯出至您想要的 Api。 如此一來,實作變更時,標準 dll 裡仍然有效。
與靜態連結至 MFC 的標準 Dll、 DLL 和應用程式使用 MFC,如果沒有與想要在不同版本的 MFC DLL 比或從 web 伺服器的應用程式的問題。 因為 MFC 程式庫以靜態方式連結到每個 DLL 或 EXE 中,沒有任何問題,您有哪一個版本。
API 限制
某些 MFC 功能並不適用於 DLL 版本,可能是因為技術限制,或因為應用程式通常提供這些服務。 與 MFC 的目前版本,並不適用的唯一函式是CWinApp::SetDialogBkColor。
建置您的 DLL
編譯以靜態方式連結至 MFC,符號的標準 Dll 時_USRDLL和_WINDLL必須定義。 您的 DLL 程式碼也必須使用以下的編譯器選項進行編譯:
/D_WINDLL表示編譯為 DLL 的
/D_USRDLL指定您正在建置標準 DLL
您也必須定義這些符號,並使用這些編譯器選項,當您編譯動態連結至 MFC 的標準 dll 裡。 此外,該符號_AFXDLL必須定義和必須以編譯您的 DLL 程式碼:
- /D_AFXDLL指定您要建立動態連結至 MFC 的標準 DLL
必須明確地匯出應用程式和 DLL 之間的介面 (Api)。 我們建議您定義為低頻寬,將介面,如果可以的話,請使用只 c 的介面。 直接 c 的介面較為方便維護比更複雜的 C++ 類別。
將您的 Api 放在個別的欄位名稱可包含 c 與 C++ 檔中。 請參閱 MFC 進階概念的範例中的標頭 ScreenCap.h DLLScreenCap 的範例。 若要匯出您的函式時,請輸入在EXPORTS您的模組定義檔的區段 (。DEF) 或包含**__declspec(dllexport)在您的函式定義上。 使用__declspec(dllimport)**將這些函式匯入用戶端可執行檔。
您必須將AFX_MANAGE_STATE在動態連結至 MFC 的標準 dll 裡所有匯出的函式的開頭的巨集。 此巨集將目前模組狀態設定為 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 連結
以靜態方式連結至 MFC 的標準 dll 裡,您必須連結您 Nafxcwd.lib 或 Nafxcw.lib,使用的名稱為 Libcmt.lib 的 c 執行階段版本的 DLL。 這些程式庫會預先建立的並可能藉由使用 Visual C++ 安裝程式時,請指定其安裝。
程式碼範例
請參閱程式 DLLScreenCap 如需 MFC 進階概念範例。 這個範例中應該注意數個有趣的事情是,如下所示:
DLL 的編譯器旗標及的應用程式也會有所不同。
連結線和。DEF 檔的 DLL 及那些應用程式也會有所不同。
在 C++ 中沒有使用該 DLL 的應用程式。
應用程式和 DLL 之間的介面是一套 API,可由 c 或 C++ 中,並會匯出與 DLLScreenCap.def。
下列範例說明以靜態方式連結至 MFC 的標準 DLL 中定義的 API。 在這個範例中,該宣告包含在extern "C" { } C++ 使用者的區塊。 這有許多好處。 首先,這會讓您的 DLL Api 可使用非 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 程式。