2012-09-07 83 views
2

我需要從另一個DLL中加載一個DLL。誘惑是將它加載到DllMain中,但已經有令人信服的文檔說明它是一個「壞主意」。有從另一個DLL中加載DLL的最佳做法嗎?

冒着問一個不是很具體的問題:是否有從另一個DLL加載DLL的最佳做法?

在我們當前的項目中,我們的主DLL有一個類。我從該類的構造函數中加載第二個DLL。但是,由於該類可以在DLL中多次實例化,因此我在其周圍保留一個變量以指示是否先前加載了DLL,以便不再次調用LoadLibrary。這不知何故不覺得這是一個好的解決方案,因此我的問題。

+2

對於它的價值,你的解決方案根本不算什麼 - 這是非常普遍的。這是一個簡單而優雅的方法來解決這個問題,而不需要在DLL中增加一些額外的初始化函數。我會把它放在像'EnsureOtherDLLLoaded'之類的函數中。 – tenfour

+1

你的解決方案很好。事實上,你甚至不需要跟蹤它是否已經被加載。在這個過程中再次調用LoadLibrary是很好的。 Windows將爲該庫保留引用計數,並且不會卸載它,直到FreeLibrary調用的次數與LoadLibrary調用的次數相匹配。 –

回答

3

這取決於你的DLL。 基本上,你有以下選擇:針對DLL的LIB

  1. 鏈接自動
  2. Load當你的庫加載,卸載,然後再將其卸載
  3. 負載使用前其他DLL其他DLL加載它,然後卸載

如果您選擇1,如果DLL2在嘗試加載DLL1時丟失,您會得到非常奇怪的消息,例如「無法加載DLL1」。而客戶永遠不會知道這是因爲缺少DLL2。所以我不喜歡使用這個解決方案,如果你不能100%確定DLL2安裝正確的話。

但是,當您手動加載DLL2(LoadLibrary)時,您將有機會呈現有意義的消息。

如果在DLL中有明確的入口和出口點,則可以選擇2。如果您的DLL導出一個或很少的函數,即爲其他對象創建工廠的函數,就是這種情況。然後你可以加載/卸載工廠。

如果這不會導致您頻繁地執行此加載/卸載,您可以選擇3。

此外,您不需要只保留一個DLL2句柄。您可以多次調用LoadLibrary/FreeLibrary,它是執行引用計數的框架。

因此,根據您的情況,您可以選擇這三種解決方案之一。只有當您沒有明確的入口點並且您正在調用需要DLL2的函數時,您才必須使用原始解決方案。

+0

這聽起來像你告訴他他可以隨意多次LoadLibrary多次,從0遞增一個變量,並且框架將爲他引用計數,並且不會有大量開銷。然後在退出時,隨着變量增加,多次調用FreeLibrary。 –

+0

當然有一些開銷,但它相對較小。我剛剛檢查過它:第二個LoadLibrary返回與第一個(p1)相同的指針(p2)。所以這個庫不是第二次加載,只是同一個habdle被重用。 然後你可以FreeLibrary(p2)並繼續使用p1。當然,加載和卸載的總數應該匹配。 – Steed

+0

第二個LoadLibrary是否會導致第二個DLLMain第二次執行? –