在 Visual Studio 中建立 C++ DLL

在 Windows 中,動態連結程式庫 (DLL) 是一種可執行檔,可作為函式和資源分享程式庫。 動態連結是作業系統功能。 它可讓可執行檔呼叫函式或使用儲存在個別檔案中的資源。 這些函式和資源可以與使用它們的可執行檔分開編譯和部署。

DLL 不是獨立的可執行檔。 DLL 會在呼叫它們的應用程式內容中執行。 作業系統會將 DLL 載入應用程式的記憶體空間。 當應用程式載入時( 隱含連結 ),或在執行時間視需要完成 ( 明確連結 )。 DLL 也讓您輕鬆地在可執行檔之間共用函式和資源。 多個應用程式可以同時存取記憶體中單一 DLL 複本的內容。

動態連結與靜態連結之間的差異

靜態連結會將靜態程式庫中的所有物件程式碼複製到建置時使用它的可執行檔。 動態連結僅包含 Windows 在執行時間尋找和載入包含資料項目或函式的 DLL 所需的資訊。 當您建立 DLL 時,也會建立包含此資訊的匯入程式庫。 當您建置呼叫 DLL 的可執行檔時,連結器會使用匯入程式庫中匯出的符號來儲存 Windows 載入器的資訊。 載入器載入 DLL 時,DLL 會對應至應用程式的記憶體空間。 如果存在,則會呼叫 DLL DllMain 中的特殊函式來執行 DLL 所需的任何初始化。

應用程式和 DLL 之間的差異

即使 DLL 和應用程式都是可執行檔模組,但兩者在數種方式上都不同。 最明顯的差異是您無法執行 DLL。 從系統的觀點來看,應用程式和 DLL 之間有兩個基本差異:

  • 應用程式可以同時在系統中執行多個實例。 DLL 只能有一個實例。

  • 應用程式可以載入為進程。 它可以擁有堆疊、執行執行緒、全域記憶體、檔案控制碼和訊息佇列等專案。 DLL 無法擁有這些專案。

使用 DLL 的優點

動態連結至程式碼和資源比靜態連結提供數個優點:

  • 動態連結可節省記憶體並減少交換。 許多進程都可以同時使用 DLL,在記憶體中共用 DLL 唯讀部分的單一複本。 相反地,使用靜態程式庫建置的每個應用程式,都有 Windows 必須載入記憶體的完整程式庫程式碼複本。

  • 動態連結可節省磁碟空間和頻寬。 許多應用程式可以在磁片上共用 DLL 的單一複本。 相反地,使用靜態程式庫建置的每個應用程式都有連結至其可執行映射的程式庫程式碼。 這使用更多的磁碟空間,並需要更多的頻寬來傳輸。

  • 維護、安全性修正和升級可能更容易。 當您的應用程式在 DLL 中使用一般函式時,您可以實作錯誤修正,並將更新部署至 DLL。 更新 DLL 時,使用這些 DLL 的應用程式不需要重新編譯或重新連結。 只要部署新的 DLL,他們就可以使用新的 DLL。 相反地,當您在靜態連結的物件程式碼中進行修正時,您必須重新連結並重新部署使用該程式碼的每個應用程式。

  • 您可以使用 DLL 提供市場後支援。 例如,可以修改顯示驅動程式 DLL 以支援應用程式出貨時無法使用的顯示器。

  • 您可以使用明確的連結,在執行時間探索和載入 DLL。 例如,將新功能新增至應用程式的應用程式延伸模組,而不需重建或重新部署。

  • 動態連結可讓您更輕鬆地支援以不同程式設計語言撰寫的應用程式。 以不同程式設計語言撰寫的程式只要程式遵循函式的呼叫慣例,就可以呼叫相同的 DLL 函式。 程式和 DLL 函式必須以下列方式相容:函式預期其引數推入堆疊的順序。 函式或應用程式是否負責清除堆疊。 而且,是否在暫存器中傳遞任何引數。

  • 動態連結提供擴充 Microsoft Foundation Class 程式庫 (MFC) 類別的機制。 您可以從現有的 MFC 類別衍生類別,並將其放在 MFC 擴充 DLL 中,以供 MFC 應用程式使用。

  • 動態連結可讓您更輕鬆地建立應用程式的國際版本。 DLL 是提供地區設定特定資源的便利方式,可讓您更輕鬆地建立應用程式的國際版本。 您可以將每個語言的字串和影像放在個別的資源 DLL 中,而不是傳送許多當地語系化的應用程式版本。 然後您的應用程式可以在執行時間載入該地區設定的適當資源。

使用 DLL 的潛在缺點是應用程式並非獨立式。 這取決於個別 DLL 模組是否存在:您必須部署或驗證自己作為安裝一部分的 DLL 模組。

如何建立和使用 DLL 的詳細資訊

下列文章提供如何在 Visual Studio 中建立 C/C++ DLL 的詳細資訊。

逐步解說:建立和使用動態連結程式庫 (C++)
描述如何使用 Visual Studio 來建立並使用 DLL。

DLL 的種類
提供關於各種不同可建置 DLL 的資訊。

DLL 常見問題
提供 DLL 常見問題的解答。

將可執行檔連結至 DLL
說明 DLL 的明確和隱含連結方式。

初始化 DLL
討論 DLL 載入時必須執行的 DLL 初始化程式碼。

DLL 和 Visual C++ 執行階段程式庫行為
描述執行時間程式庫 DLL 啟動順序。

LoadLibrary 和 AfxLoadLibrary
討論在執行時間使用 LoadLibraryAfxLoadLibrary 明確連結至 DLL。

GetProcAddress
討論如何使用 GetProcAddress 來取得 DLL 中匯出函式的位址。

FreeLibrary 和 AfxFreeLibrary
討論不再需要 DLL 模組的使用 FreeLibraryAfxFreeLibrary 時機。

動態連結程式庫搜尋順序
說明 Windows 作業系統在系統上找出 DLL 時所用的搜尋路徑。

以動態方式連結至 MFC 之一般 MFC DLL 的模組狀態
描述一般 MFC DLL 動態連結至 MFC 的模組狀態。

MFC 延伸模組 DLL
說明通常實作衍生自現有 MFC 類別之可重複使用類別的 DLL。

建立僅限資源 DLL
說明僅含資源 DLL,這種 DLL 只會包含資源,例如,圖示、點陣圖、字串和對話方塊。

MFC 應用程式中的當地語系化資源:附屬 DLL
提供對附屬 DLL 的增強支援,這項功能可協助建立當地語系化成多國語言的應用程式。

匯入和匯出
說明將公用 (Public) 符號匯入應用程式,或是從 DLL 匯出函式的方法。

主動技術和 DLL
讓物件伺服程式可以於 DLL 內實作。

DLL 中的 Automation
說明 MFC DLL 精靈提供的 Automation 選項。

MFC DLL 的命名慣例
討論包含在 MFC 的 DLL 和程式庫如何遵守結構化的命名慣例。

從 Visual Basic 應用程式呼叫 DLL 函式
說明從 Visual Basic 應用程式呼叫 DLL 函式的方式。

使用 MFC 作為 DLL 的一部分
描述一般 MFC DLL,可讓您使用 MFC 程式庫做為 Windows 動態連結程式庫的一部分。

MFC 的 DLL 版本
描述如何使用 MFCxx.dll 和 MFCxxD.dll(其中 x 是 MFC 版本號碼)與 MFC 應用程式和 MFC 擴充功能 DLL 共用動態連結程式庫。