斯蒂芬T. Lavavej時,Visual C++的STL實現的關鍵作者所設定的規則在此Reddit thread:
這裏有精確的規則:
如果您有任何C++標準庫頭,你必須遵守其規則,並且我們有意破壞主要版本之間的二進制兼容性(但是在修補程序和服務包之間保留它)。任何表示更改(包括但不限於添加/刪除數據成員)都會破壞二進制兼容性,這就是爲什麼總是會發生這種情況,爲什麼我們會謹慎地保護這一權利。
[剪斷]
所以,如果你在STL的規則玩,你需要確保以下幾點:
- 所有目標文件和鏈接到一個單一的二進制靜態庫( EXE/DLL)必須使用相同的主版本進行編譯。我們添加了鏈接器檢查,以便VS 2010+主要版本不匹配將在鏈接時觸發嚴重錯誤,但如果涉及VS 2008或更早版本,我們無法幫助您(無時間機器)。由於ODR適用於此,因此您應該對所有對象文件和靜態庫使用相同的工具集(即相同的Service Pack級別)。例如,我們修復了VS 2010 RTM和SP1之間的std :: string內存泄漏,但是如果混合使用RTM和SP1,則生成的二進制文件可能會受泄漏的影響,也可能不會受到泄漏的影響。 (另外,您需要使用相同的_ITERATOR_DEBUG_LEVEL和釋放/調試設置;我們現在有這些鏈接器檢查。)
- 如果有多個二進制文件加載到同一個進程中,並且它們將C++標準庫對象傳遞給彼此,那些二進制文件必須使用相同的主要版本和_ITERATOR_DEBUG_LEVEL設置(釋放/調試應該也匹配,我忘記了,如果你在這裏可以避免失配)。重要的是,我們無法檢測到違反此規則的情況,因此您需要遵循此規則。
- 其接口純粹是C或COM(或現在的WinRT)的多個二進制文件可能在內部使用不同的主版本,因爲這些東西保證了二進制兼容性。如果你的接口涉及C++核心語言(例如帶有虛擬的東西),但是非常小心,從不提及任何C++標準庫類型,那麼你可能沒問題 - 編譯器確實試圖避免破壞二進制兼容性。
但是,請注意,當加載到一個進程中的多個二進制文件使用不同的主要版本進行編譯時,幾乎可以肯定最終會有多個CRT加載到您的進程中,這是不可取的。底線 - 如果你一貫地編譯所有東西100%,你就不必擔心這些東西。如果你可以避免混合遊戲,不要玩混合遊戲。
我似乎沒有找到任何有關此更新導致ABI損壞的信息。 – dtech 2013-04-05 14:42:26
@ddriver:我也沒有找到關於_not_破解ABI的任何信息,因爲它是MS Visual Studio,所以你永遠不知道... – Bloops 2013-04-05 16:34:57
測試將是找出最快的方法。鏈接到一些較大的DLL,它有很好的破壞二進制兼容性的可能性。然後你將成爲第一個知道的人。 ;) – dtech 2013-04-05 16:37:08