2008-10-31 48 views
3

我已經繼承了一個非常大且複雜的項目(實際上是一個'解決方案',由119個'項目'組成,其中大部分都是DLL),它是在VC8(VS2005)下構建和測試的,我有任務將其移植到VC9(VS2008)。什麼是從VC8(VS2005)要VC9(VS2008)的移植問題是什麼?

我用的移植過程是:

  1. 複製VC8 .sln文件並重新命名它 到VC9 .sln文件。
  2. 複製全部 VC8項目文件,並將它們重命名爲 它們爲VC9項目文件。
  3. 編輯 所有的VC9項目文件, s/vc8/vc9。
  4. 編輯VC9的.sln, S/VC8/VC9/
  5. 裝入VC9的.sln與 VS2008,並讓IDE '轉換' 所有項目文件。
  6. 修復 編譯器和鏈接器錯誤,直到我 得到了良好的構建。

到目前爲止,我在最後一步遇到了以下問題。

1)修飾裝飾名稱的方式發生變化,導致名稱被截斷。

這不僅僅是一個警告(http://msdn.microsoft.com/en-us/library/074af4b6.aspx)。使用此警告構建的庫不會與其他模塊鏈接。應用MSDN中給出的解決方案並不重要,但可行。我在How do I increase the allowed decorated name length in VC9 (MSVC 2008)?

中分別解決了這個問題2)一個不允許將零賦值給迭代器的更改。這是根據規範,並且很容易找到並修復這些之前允許的編碼錯誤。而不是將零賦值給迭代器,請使用值end()。

3)for-loop範圍現在按照ANSI標準。另一個易於修復的問題。

4),用於預編譯頭需要更多的空間。在某些情況下,需要更多的空間。我最終使用/ Zm999來提供最大的PCH空間。如果PCH內存使用獲取再撞,我認爲我將不得不完全放棄PCH,只是忍受什麼已經是一個很長的編譯時間的增加。

5)副本和默認dtors的需求變化。目前看來,在模板類,在我還沒有完全想通了,但某些情況下,編譯器不再生成默認構造函數或默認的析構函數。我懷疑這是VC9中的一個錯誤,但可能有其他的我做錯了。如果是這樣,我肯定想知道它是什麼。

6)sln和vcproj文件中的GUID沒有改變。這似乎沒有以我能檢測到的任何方式影響構建,但仍然令人擔憂。

請注意,儘管存在所有這些問題,該項目在VC8下構建,運行並通過了廣泛的QA測試。我也背移植的所有更改VC8項目,他們仍然生成並運行一樣愉快地爲他們(使用VS2005/VC8)以前那樣。因此,對於VC9構建所需的所有更改似乎都是向後兼容的,儘管迴歸測試仍在進行中。

現在真正的難題:我遇到了VC8和VC9項目之間啓動順序的差異。該程序使用在Loki之後建模的小對象分配器,在Andrei Alexandrescu的Book Modern C++ Design中。該分配器使用主程序模塊中定義的全局變量進行初始化。

在VC8下,這個全局變量是在程序啓動的最開始時從模塊crtexe.c中的代碼構建的。在VC9下,執行的第一個模塊是crtdll.c,表示啓動順序已更改。在全局對象可以初始化統計信息之前,啓動的DLL似乎通過分配和釋放內存來混淆小對象分配器,這會導致一些虛假的診斷。程序的運行似乎沒有受到實質性影響,但QA人員不允許虛假診斷通過它們。

是否有某種方法可以在加載DLL之前強制構造全局對象?

我可能會遇到什麼其他移植問題?

回答

0

這當然是一個有趣的問題。除了可能更改設計之外,我沒有解決方案,因此不會依賴未定義的訂單或鏈接/ dll啓動行爲。你有沒有考慮與舊的鏈接器鏈接? (或任何VS.NET項)

因爲你的變量和分配行爲上的一些(當時未知)啓動的任意順序,我可能會修復的依賴,使得它不是對未來的問題。我想你真的在問,如果有人知道如何在VC9中做一些巫術來讓問題消失。我也有興趣聽到它。

1

是否有某種方法可以在加載DLL之前強制構造全局對象?

DELAYLOAD選項如何?所以這些DLL在第一次調用之前不會被加載?

0

這個怎麼樣,

  1. 讓你的主程序DLL也稱之爲main.dll,聯繫到所有其他的人,並導出主要功能說,mainEntry()。刪除全局變量。
  2. 創建一個新的主exe文件,它具有全局變量及其初始化,但不會靜態鏈接到任何其他應用程序dll(分配器的東西除外)。
  3. 這個新的main.exe然後使用LoadLibrary()動態加載main.dll,然後使用GetProcAddress調用mainEntry()。
1

這是一個棘手的問題,主要是因爲您已經繼承了一個本質上危險的設計,因爲您不應該依賴全局變量的初始化順序。

這聽起來像是你可以嘗試解決全局變量與其他函數檢索通過調用一個全局函數或返回一個指向單例對象的方法的全局變量。如果對象在調用時存在,則該函數返回一個指向它的指針。否則,它會分配一個新的對象並返回一個指向新分配的對象的指針。

的問題,當然,是,我想不出一個單身的實施,將避免您所描述的問題。也許這次討論將是有益的:http://www.oneunified.net/blog/Personal/SoftwareDevelopment/CPP/Singleton.article

+0

原來,使用單身人士是最好的答案。謝謝! – 2014-08-07 16:22:56

0

的解決問題的方法竟然是更直接,比我原來想象。初始化順序問題是由存在幾個從std容器類型派生的類型的全局變量(一個基本的設計缺陷超出了我對該公司的立場)而引起的。解決方案是用單例替換所有這些全局變量。其中大約有100個。

一旦這樣做,初始化(和破壞)順序爲程序員控制之下。