共用方式為


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 程式。

請參閱

其他資源

技術的備忘稿編號

依類別的技術注意事項