小斯同窗花了幾周的時間,終於把咱們的服務端和客戶端從vs2005升級到vs2013了。真是不得不給個贊。
升級的過程當中遇到了各類問題,小斯同窗跋山涉水、越過艱難險阻終於成功讓咱們用上了高大上的宇宙第一IDE——vs2013。因此這裏我順帶把他升級中遇到的問題記錄一下,也許對一些朋友是種參考。
首先,須要說明一下,以前在csdn上看到有人提了一個問題:爲何好多遊戲都用VS2005開發呢?原帖子在這裏:http://bbs.csdn.net/topics/390645505html
下面的回覆也是五花八門。這裏做爲從業人員,我談一下感覺,首先用vs2005仍是用vs2012甚至vs2013只是一個選擇問題,換句話說,只要願意,咱們能夠拿什麼亂七八糟的玩意開發都沒問題。
再來講下實際的,爲何大多數遊戲公司都用vs2005開發呢?我其實不知道那個樓主說魔獸世界和憤怒的小鳥是用vs2005開發的,但咱們的遊戲確實是拿vs2005開發的,並且我知道的一些遊戲公司也確實拿vs2005開發,那麼爲何呢?由於項目就是在那個時候建立的,而那個時候正好手頭上熟悉的開發工具就是vs2005,憤怒的小鳥2009年發行的第一個版本,其開發公司Rovio公司成立於2003年,他們公司以前固然不會打醬油了,因此目測以前咱們用的不是vs2005,由於那個時候尚未vs2005呢,估計有了vs2005以後,他們公司升級到vs2005做爲開發工具了,而vs2008要等到07年末纔出來,若是他們的程序們不想升級,天然是沒人會去升的,而魔獸世界咱們都知道是04年就出了,因此那個時候你總不能說他們的開發工具是vs2005吧。因此魔獸若是真的在用vs2005,那也是以後升級到vs2005的。至於爲何不繼續升級到vs2008或者是vs20十、十二、13等,個人見解是,沒有需求。公司的目的是盈利,而若是從vs2005升級到vs2013沒法提升收益,那麼爲何要升級,既然公司不會爲你升級而發獎金或者是工資,天然沒人閒的蛋疼去升級,還要處理一堆的升級以後的問題。
還有一點緣由,由於用戶看到的那個程序並不是是由程序員來「控制」用什麼編譯的,固然這裏的控制是打引號的,聽我慢慢解釋,在公司升級開發工具並不是跟本身玩玩同樣簡單,首先,通常公司編譯代碼都是配有編譯機的,就是說程序員在本身本地用開發工具來編寫調試代碼以後經過各類版本控制工具,好比svn或者git之類的提交到代碼庫裏,而後由編譯機來編譯出真正的供使用的版本,因此,若是你想升級開發工具就要同時升級本身的開發工具和編譯機的編譯配置,通常而言,公司的編譯機都有專門的人來管理的,也就是所謂的配置管理員之類的職位,他們負責管理編譯機,程序員固然能夠在本地用各類開發工具進行開發,只要你可以保證代碼編譯沒有問題,誰管你是用vs2013開發仍是用記事本在寫代碼?可是程序員若是想要控制輸出到外網的版本是用什麼編譯工具來編譯的話,就要說服配置管理員來升級編譯機上的配置,而通常公司而言,這都是不可能的,由於程序員壓根管不到配置管理員,若是不是項目經理點頭首肯,配置管理員爲何要聽你程序員的,而程序員若是要說服項目經理,那麼就要擺出各類厲害關係,好比vs2013如何碉堡(誰管你碉不碉堡)、如何能提升開發效率(尼瑪不升級你效率就低下嗎?)、vs2013可以給用戶帶來飛通常的體驗(即便你信口開河,項目經理也不必定信)。即便你口才非凡的說服了項目經理,他贊成讓公司花一筆錢把新的IDE買下來供你們使用,你還須要說服其餘的程序員,由於你一旦修改了項目的編譯工具,必然要影響到其餘程序員的開發,固然咱們必須可以說服其餘程序員,讓他們改變開發習慣。總結一下:
一、你須要說服項目經理,讓他申請花費一筆錢購買新的vs
二、你要說服配置管理員,讓他更改編譯機的配置,頗有可能你須要幫助他解決新配置下的各類問題,而也許你並不擅長
三、你須要說服別的程序員,讓他們改變開發習慣,適應新的開發工具
四、最後你須要解決大家項目工程由vs2005升級到vs2013的各類詭異bug,保證升級以後大家的用戶不會在使用上有問題。
固然,這是從程序員推進去升級開發工具,若是從項目經理推進的話,就容易的多了,一句話「大家都給我用vs2013開發」,其餘的事情天然有人去完成了,程序員要作的不過是安裝一下vs2013罷了。可是有多少項目經理是真正關心程序員拿什麼開發,又或者程序最後拿什麼編譯的呢?呵呵!其實只有程序員關心這些。我相信全部跟我同樣的程序員都是喜歡嘗試新鮮事物的,因此不少狀況下,你雖然看到的程序是用vs2005編譯的,實際上我頗有多是用着vs2013在作開發,只不過編譯給你的是vs2005編譯的罷了:)
回到正題,咱們項目升級過程當中遇到了哪些問題呢?這裏我分別挑幾個顯著的問題說一下:
工程自動轉換
首先vs2013對vs2005的工程是兼容的,也就是說你能夠直接用vs2013打開vs2005的工程,固然,vs2013會對vs2005的工程文件作一番轉換。找到vs2005的sln文件,用vs2013打開完成轉換後又日誌報告,通常來講不會有什麼問題,若是你想仔細看也能夠,點進去看就是的:git
這裏要注意一點,在轉換sln的時候,咱們的vs2013掛掉了,最後咱們發現是有一個工程的vcproj文件裏有引號字符的html代碼,這個在vs2005下是能夠識別的,可是用vs2013去轉換它的時候卻把vs2013給弄死掉了,去掉就能夠了程序員
工程設置上的不一樣
還有一點就是在vs2005和vs2013工程配置裏有好多默認設置竟然是不一樣的,好比輸出目錄,vs2013的路徑最後會添加一個 ‘\’,而vs2005下卻沒有。這個最初看上去沒什麼影響,可是咱們的工程本身定義了路徑宏的時候添加了末尾的符號‘\’,致使在vs2013下路徑就多了一個‘\’。windows
解決方案打開後通常來講各個工程的組織結構不會變更,這個時候沒關係着對整個解決方案進行編譯,建議一個工程一個工程的編譯,這樣解決問題起來比較清晰。
vs2013和vs2005另外一個比較大的變化就是VC++的目錄設置,在vs2005裏面這個目錄設置是針對全部工程的總設置,在Tools->Options->Projects and Solutions->VC++ Directories下,而在vs2013裏,這個設置放到了每一個工程設置下,在Project->Properties->VC++ Directories下,位置變化到是次要的,問題是vs2013把不少頭文件放到了系統的一個目錄,並且文件內容還發生了變化。svn
系統宏的不一樣
好比咱們用到了一個系統的宏:OutputDebugStr,它在vs2005的頭文件裏定義在vs安裝目錄下的平臺sdk目錄下的mmsysytem.h,而到vs2013下這個文件被放到了系統目錄的sdk下,並且這個宏的定義還消失了。函數
解決辦法也比較簡單,在工程的預編譯文件裏添加一下這個宏的定義,注意兼容vs2005和vs2013版本就行:工具
1
2
3
|
#ifndef OutputDebugStr
#define OutputDebugStr OutputDebugString
#endif
|
其餘未定義宏的解決方案也相似。只有有一類屬於宏的定義值自己就不一樣,好比,咱們遇到這麼一個問題:
開發工具
這個變量是定義在wingdi.h文件中的,可是在vs2013新的sdk下和vs2005的windows的sdk下這兩個定義是不一致的,vs2005下是這麼定義的:
spa
vs2013下是這麼定義的:.net
目前咱們的解決方案只是從新定義一下這個宏:
1
2
3
|
#if (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
#define CLEARTYPE_QUALITY 5
#endif
|
事實上,vs2013下windows的SDK版本和vs2005自帶的SDK版本是有區別的,vs2013的SDK版本是0x0603,而vs2005的版本是0x0500。因此會有一批這種問題出現,其實你能夠直接把這個版本號進行修改,這樣就可使用vs2005下的版本內容了。雖然我不知道sdk是否向後兼容,不過應該是兼容的,能夠試下。
命名空間的檢查更加嚴格
咱們的程序引用了一個之前用C寫的庫,裏面用到了一個結構體名字叫:is_base_of,結果沒想到vs2013用的std命名空間裏有一個同樣的名字,因此咱們的解決方案是給咱們本身寫的結構體加上了一個命名空間。
1
2
3
4
5
|
namespace
test {
struct
is_base_of {
...
};
};
|
dx頭文件的不一樣
咱們都知道vs2013已經集成了dx的sdk,而不像以前同樣單獨發佈dx的sdk,同時,vs2013把dx的頭文件放到了系統的sdk目錄裏。在上面咱們提到過vs2013和vs2005的VC++目錄設置不一樣,vs2013包含了系統的sdk目錄,這致使了一個問題。舉個例子就明白了,由於咱們的客戶端程序用到了dx9,而爲了保證版本的一致性,咱們把dx9的頭文件放到了工程目錄當中,在vs2005下,咱們不須要特別指明dx的頭文件目錄,由於系統的默認目錄裏是沒有dx的頭文件的,不管咱們是用<>仍是""的方式來先查找系統目錄仍是先查找工程目錄最後都只能找到咱們工程的dx頭文件,可是在vs2013下咱們必需要把咱們本身的dx目錄放進工程的VC++目錄裏,這樣才能保證咱們引用的是本身的頭文件而不是系統的。順帶說一下,VC++目錄和在C/C++選項卡下的附加包含目錄有什麼區別:
配置在VC++目錄裏的路徑,在用 <> 包含的時候會優先查找,而配置在C/C++ 選項卡下的附加包含目錄在用 "" 包含的時候會優先查找。
VS自帶庫的實現不一樣
這個就比較糾結了,由於兩個VS的版本存在差別,不免會出現庫的實現不一樣的狀況,好比咱們遇到的一個問題:
咱們打開兩個VS的安裝目錄下 VC\include queue文件,對比以後發現,這兩個queue的實現還真是差異大,咱們的問題在於本來是一個public的成員變量,如今變成了protected了:
不過好在變爲protected以後,它提供了一個成員函數來獲取它,這沒辦法了,咱們只能修改咱們本身的代碼,把原來直接獲取改成用成員函數來獲取。
本文出自 「菜鳥浮出水」 博客,請務必保留此出處http://rangercyh.blog.51cto.com/1444712/1394348