2013-10-14 97 views
3

我想知道,是否調用放置在.dll中的代碼,使用不同的工具鏈構建該代碼?並且正在使用一個.lib文件與一個較舊的編譯器一起構建一個更新的代碼。使用不同編譯器的版本構建的混合二進制文件

我知道,第二個是不可取的,但我想知道,這是不可能的。

正是我的情況是這樣的:

a.exe文件使用b.lib文件,該文件也與VC7.1內置VC7.1建。 a.exe來自c.dll的調用代碼也是使用b.dll構建的。現在我想寫一個新的c.dll,但用VC9編譯它。 (我想這樣做,因爲我需要一些不支持使用VC7.1構建它們的庫。) - 我的c.dll也需要b.lib,我仍然有它的來源,因此我可以重新編譯它。

那麼,是否有可能使其工作?如果不是,你能提供一個簡短的解釋,究竟是什麼不允許這樣做?

+0

一個大問題是你會得到一個不同的CRT,這意味着你得到一個不同的堆。這會導致解除分配問題。 – drescherjm

回答

8

這並非完全不可能。主要的問題是,你將不可避免地以兩個不同的運行時庫副本結尾。每個副本保留自己的狀態並使用自己的內存分配器。必須仔細設計DLL接口以避免可能導致的可能的故障。

硬規則是你永遠不能從DLL中的代碼拋出一個異常,並在EXE中捕獲它。而且你不能從你的DLL代碼中返回一個像std :: string這樣的標準C++庫對象,它們有不同的實現,因爲它使用了不同的分配器,EXE不能正確地銷燬對象。更一般的規則是,DLL永遠不會返回指向調用者需要釋放的對象的指針。 CRT狀態可能會導致微妙的問題,如errno不會返回正確的錯誤代碼和區域設置錯誤。總之,大量的痛苦很難診斷,甚至難以修復。

COM編程模型是一個安全的例子。它從不公開實現,只有純粹的抽象接口。沒有例外,只有錯誤代碼。對象由工廠分配並且引用計數。在絕對必要的地方,它使用一個共同的堆來分配CoTaskMemAlloc()。不是流行的編程模型,但這就是它需要的。

相關問題