2013-08-16 64 views
4

我對VS2010和VS2012之間的編譯庫的二進制兼容性感到困惑。我想遷移到VS2012,但是許多僅用於開源的二進制SDK僅適用於VS2010,例如用於連接硬件設備的SDK。VS2010和VS2012之間的二進制C++庫兼容性?

傳統上,據我所知,Visual Studio對編譯器版本非常挑剔,而在VS2010中,您無法鏈接到已經爲VS2008編譯的庫。

我現在感到困惑的原因是我正在遷移到VS2012的過程中,並且我嘗試了一些項目,對於我最大的驚喜,他們中的很多人都工作在沒有問題的交叉版本中。

注意:我不是在談論v100模式,就我所知,它只是VS2012 GUI上的VS2010編譯引擎。

我正在討論在VS2012中打開VS2010解決方案,單擊更新並查看會發生什麼。

當鏈接到一些更大的庫,如boost,編譯不起作用,因爲有檢查編譯器版本,他們提出了一個錯誤,並中止編譯。其他一些圖書館只是在缺少功能時放棄。這是我期待的行爲。

另一方面,許多庫工作正常,沒有錯誤或額外的警告。

這怎麼可能? VS2012是否以特殊的方式保持與VS2010庫的二進制兼容性?它依賴於動態鏈接還是靜態鏈接?

還有一個最重要的問題:即使在編譯時沒有提出錯誤,我可以相信編譯器將VS2012項目鏈接到VS2010編譯庫時不會有任何錯誤嗎?

+1

「他們中的很多人工作的跨版本沒有問題。」 只有你知道。更有可能的是,他們恰好匹配99%的時間,並且_seem_正在工作。傳遞'std :: deque'可能不會顯示編譯器錯誤,但可能會崩潰。 –

+0

VS2012環境確實在尋找你的各種構建工具鏈,並允許你使用它們作爲v110(或者CTP)的替代品。它不是VS2012在一些神奇的替代宇宙中運行。它實際上只是使用你所說的任何用於構建實現的東西。這也是CTP如何在您的閒暇時間使用(或不使用)。 – WhozCraig

+2

stdlib在版本之間沒有二進制兼容性。有太多的內聯和改變數據結構。另請參閱[如何在C++中構建運行時版本不可知的DLL?](http://stackoverflow.com/a/6206219/209199) –

回答

3

「許多圖書館工作正常。這怎麼可能?「

1)該lib被編譯爲使用靜態RTL,因此代碼不會拉入第二個發生衝突的RTL DLL。

2)代碼僅調用完全位於頭文件 中的函數(並使用結構等),因此不會導致鏈接器錯誤,或者調用仍然存在於新RTL中的函數,因此不會不會導致鏈接器錯誤,

3)不會調用任何具有已更改佈局或含義的結構,因此它不會崩潰。

#3是一個值得擔心的問題。您可以使用導入來查看它使用的內容並製作完整列表,但沒有文檔或保證哪些是兼容的。僅僅因爲它似乎運行並不意味着它沒有潛在的錯誤。

還有的

4)駕駛員SDK或其他代碼是相當低的水平被寫入完全避免使用標準庫調用的可能性。

也可以(不是你的情況我認爲)DLL可以被隔離,並有自己的RTL,而不是在不同的機制之間來回傳遞內存(如內存分配和釋放)。進程內COM服務器以這種方式工作。 DLL 可以這樣做一般如果你小心你傳遞和返回什麼和你做什麼像指針。例如Crypto ++是用封閉程序的內存例程初始化的,並且不會從它編譯的RTL版本中暴露出malloc的內存。

+0

是的,兼容性問題與工具鏈不兼容,它們與內存佈局常見的數據類型和假設都被嵌入到內聯函數中。 –