2011-06-30 49 views
2

我有一個DLL(A.dll)使用ATL的東西,並且不能有MFC。雖然有一些它需要的東西,但是我做了一個MFC regular DLL,名爲B.dll,它會在運行時由A.dll(通過導入庫)自動加載。普通的dll vs擴展dll

A需要的B.dll的一部分是在B.dll中定義的一個類(foo),並且該類有一些使用MFC的東西。我允許在A.dll中創建一個foo對象嗎? B需要是擴展DLL嗎?

的規則DLL頁說:

一個 常規DLL中的所有內存分配應留在 DLL內;該DLL不應該傳遞給或 從主叫可執行 收到以下的:

  • 指針到MFC對象

  • 指針到存儲器由MFC

分配但擴展DLL頁面說

客戶端可執行文件必須是使用_AFXDLL編譯的MFC應用程序,並且A.dll不能是MFC應用程序。

在這種情況下使用規則的DLL是否是一個問題?

感謝,

布萊恩

回答

1

也許我誤解了,但如果A不能使用MFC,而B提供了一個類,那麼如何在A中實例化一個對象呢?你是否希望B有一個工廠函數來創建對象並通過指針將它傳遞給A?在這種情況下,您需要確保B調用delete()而不是A,因爲它們會有兩個不同的堆。

這是一個COM對象,或者你是什麼意思的'導入庫'?我們是否正在使用.lib中的存根或'導入庫'.tlb來「定期」dll方式? (不是說我認爲這個問題很重要,我只是想描繪一下情況)。

+0

我最初有A創建一個在B中定義的MFC對象。我認爲這是什麼導致我的堆錯誤。我現在將其更改爲一個函數,其中對象的生命週期由B管理,並且A訪問通過導出的函數進行。 這不是一個COM對象。導入庫是由編譯器或鏈接器生成的.lib文件,或者當您將某些內容指定爲__declspec(dllexport)或def文件時生成的.lib文件。然後任何導入和導入庫的鏈接都會在運行時自動加載dll。 – bdwain

+0

好的,這很清楚。是的,跨越dll邊界混合新/刪除有時會產生意想不到的結果。由於dll可能會與其他dll共享一個堆,並且在安裝CRT更新時,它開始使用自己的堆(取決於清單設置),從而加劇了這種情況。我認爲,通常的看法是,不要讓模塊釋放由另一個模塊分配的內存,換句話說,就像你說的,每個模塊都有自己的內存管理。如果我沒有記錯的話,使用_USRDLL/_AFXDLL的dll會有不同的堆,以執行特定於MFC的事情。 – Roel

0

這似乎是一個普通的DLL是正確的選擇。

常規DLL的主要問題是,如果將它加載到MFC應用程序中,將會有兩個獨立的MFC和所有元數據副本。您發現的建議是爲了確保元數據查找不會轉到錯誤的副本。在你的情況下沒有問題。