2012-01-16 59 views
5

在我的公司,我們最近從VC9切換到VC10。混合運行時可行的解決方案?

我們遷移了我們的項目,但是負責人告訴我們,我們必須在生產計算機上保留一些用VC9編譯的基本常見DLL。

這些DLL使用自定義結構,其中一些包含std::vector,std::map等。現在,我注意到標準容器的尺寸發生了變化:有些變大了,有些變小了。因此,我們的自定義結構的大小也發生了變化。

爲了解決由尺寸變化引起的問題,我的一位同事想到了人爲地增加了結構的尺寸,以便能夠補償將來的構件尺寸變化,以便結構保持相同的尺寸,無論運行時間如何使用,防止函數調用堆棧損壞。

就我個人而言,我覺得這個「解決方案」是可怕的,因爲雖然尺寸很重要,但結構的佈局也是如此。對我而言,增加所有結構的內存佔用來解決組織問題似乎是錯誤的。

爲了簡短起見,我的問題是:在函數原型中使用非C類型時,是否可以同時使用兩個不同的運行時(使用所描述的技巧或任何其他技巧)?對於類似的情況,你有沒有好的/不好的經歷?

回答

9

STL從未保證不同主要版本之間的二進制兼容性。所以,如果你在接口上有STL類的DLL,你應該使用相同的編譯器和相同的CRT風格,用於DLL的客戶端和DLL本身。

如果你想建立DLL的,可以在不同的編譯器版本可以安全使用,你有一些選擇,如:

  1. 公開一個純C界面(DLL可以用C++編寫,但該接口必須是純C,並且C++異常不能跨越DLL邊界)。
  2. 公開在DLL接口處的抽象接口,如在此article中所解釋的。使用COM
+0

'1.'不是一個選項,但'2.'確實可以。非常感謝你的鏈接文章。 – ereOn 2012-01-16 09:04:18

+0

@ereOn:不客氣。 – 2012-01-16 09:08:20

1

您必須確保需要使用這些舊庫的任何內容都與它們鏈接,並根據這些庫的該版本附帶的頭文件進行編譯。沒有其他辦法可以做到這一點,因爲C++必須能夠看到頭文件以知道如何解決任何數據結構。

我從你的問題中得到一個印象,你將會鏈接到一些庫,而這些庫又被編譯並鏈接到VC9運行庫,在這種情況下,可能將其餘代碼與VC10鏈接起來,只要庫不在其接口中公開任何VC9庫類型即可。我說'很可能',這是一個充滿陷阱和陷阱的領域,通常我會說你應該儘可能使用相同的運行時間。你需要做的最後一件事是編譯器對於你正在討論的std :: vector版本感到困惑(即使你可以說服編譯器和鏈接器去弄明白,你也可以保證程序員也會感到困惑) 。

這很麻煩,但更簡單一些,只要堅持舊的運行時間,直到不再需要任何目標機器。

+0

謝謝你的回答。我們已經將我們的所有代碼遷移到了VC10,就好像情況並非如此糟糕,我們的源代碼版本控制(VSS)使得它很難(如果不是不可能的話)將這些變化推回,所以切換回VC9是不再是一個選項:( – ereOn 2012-01-16 09:00:24

+0

這真的不是一個版本控制系統的預期功能,我感覺對你來說,我認爲我們的版本控制解決方案會更糟糕,這是非常企業的做事情,如恢復,分支或者沒有在結賬時全局鎖定文件 – 2012-01-16 09:09:44

+1

'enterprisey'你的意思是'陳舊而功能性',對嗎?VSS真的很糟糕,我很同情。 – 2012-01-16 10:50:05

1

我之前已經做了這個,用類似的方式填充結構。是的,你可以使用兩種不同的運行時間,只要ABI是相同的,它應該可以正常工作:當結​​構開始改變尺寸時,以及將C++(ABI遍佈整個地方) DLL邊界真的很雜亂。特別是考慮到VC10對C++ 11的期待有了很多變化。我使用DLL來關心DLL,完全是爲了在二進制兼容性方面給予我的保證。

對於我來說,提供一個事情真的會吃掉它的具體情況是很難的,但是讓我這樣對你說:這是你沒有預料到的會給你帶來的錯誤,這是一個真正的黃蜂巢。

相關問題