2009-06-24 46 views
1

假設您執行以下操作:COM對象是否負責將自己的模塊保存在內存中?

1)使用LoadLibrary加載foo.dll。

2)使用GetProcAddress獲取指向函數的指針。

3)調用該函數,爲您提供對該模塊中實現的COM對象的引用。

4)通過調用FreeLibrary來釋放foo.dll。

5)調用COM對象上的方法。

你會期望第5步成功,並沒有AV?也就是說,COM對象本身負責調用LoadLibrary(再次)來增加Windows爲每個模塊保留的引用計數,從而確保它不會超過模塊?

回答

2

我期待AV。即使它今天沒有AV,這可能是一個等待發生的崩潰。

對於這樣的情況,其中通過自定義DLL導出返回COM對象,我不希望COM對象遞增DLL的引用計數 - 只要應用程序使用DL​​L中的資源顯式加載,應用程序有責任保持該DLL加載。

對於通過正常的CoCreateInstance路徑創建的進程內COM對象,DLL通常會導出DllCanUnloadNow,只要有未完成的引用就應該返回S_FALSE。

但是,沒有什麼能夠阻止COM對象通過LoadLibrary遞增DLL的引用計數 - 這樣做沒有任何違法或不安全。

4

當然不是。模塊引用計數由正常的使用方法維護 - 您正在做的是進入運行時方案的後門。通常,您使用CoCreateInstance等等來創建您的對象 - 這些是圍繞調用CoGetClassObjectDllGetClassObject的包裝。 CoGetClassObject調用CoLoadLibrary它維護dll上的引用計數。此外,您可以在類對象上調用LockServer以維護類對象的引用計數以獲得性能,但這不是確保dll保持加載狀態所必需的。

+0

非常有趣。如果我們說在步驟3中調用的函數名爲MyCreateInstance,答案會改變嗎?即它是在CoCreateInstance之後建模的?謝謝! – 2009-06-24 23:29:16

+0

否。在上面的「標準」版本中,CoLoadLibrary調用維護對dll的引用 - 只有在安全的情況下才會釋放該引用(通過查看對COM服務器中創建的對象的實時引用,或者在你的版本中,你需要確保你自己做到這一點 – 2009-06-24 23:36:31

相關問題