使用vs2010編譯CCV1.5

        最近幾天一直在糾結一個問題,就是使用vs2010編譯CCV1.5的vs2008版本的工程文件失敗。在網上找了很久,沒有直接看到有這樣的帖子,估計這個比較基礎,那我就簡單說一下我在此過程中遇到的問題,希望能幫助後面做這個工作的朋友少走彎路。

       首先使用SVN在http://nuicode.svnrepository.com/svn/ccv15/上下載CCV1.5的源碼,如果你的計算機上裝有vs2008,可以直接用它編譯,它可以直接編譯成功,但是無法運行,會提示你應用程序初始化失敗,我沒有仔細追究其原因,估計是配置的問題。我的計算機上裝的是vs2010,所以直接使用vs2010編譯。

      使用vs2010編譯時,首先要修改一下..\apps\addonsExamples\VS2008\Community Core Vision.sln和..\apps\addonsExamples\VS2008\目錄下的名叫Community Core Vision的project文件的內容,將.sln文件的Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Community Core Vision", "Community Core Vision.vcproj",中的修改爲Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XXX", "XXX.vcproj", 其中“XXX”表示你自己定義的名字,然後將project文件的Name="Community Core Vision"修改爲Name="XXX",並且將這兩個文件的文件名也修改爲XXX。修改完畢後就使用vs2010打開解決方案文件,最好在轉換是選擇備份,然後轉換完後顯示轉換日誌。

      打開轉換日誌,可以看到warning MSB8012: TargetPath(...) does not match the Linker's OutputFile property value等提示,意思是宏‘TargetPath’和TargetName’與你的輸出清單文件的路徑和名字不匹配,那麼就要進行適當修改。我的vs2010是中文版本的,首先點擊工程屬性->屬性配置->常規頁中的輸出目錄設置爲\bin,調試頁中的命令項設置爲$(TargetPath),這個宏指向\CCV1.5\apps\addonsExamples\VS2008\bin\XXX.exe,到時編譯後的.exe文件就在bin目錄下,主要是爲了其能連接裏面的dll,然後鏈接器->常規頁中輸出文件項設置爲$(OutDir)XXX.exe這樣保證了TargetName’與.exe的文件名的匹配性。爲什麼要這樣做,可以參見這篇blog

     當以上都設置好後,就可以編譯了,第一次編譯會提示這樣的錯誤:

    

1>c:\program files\microsoft visual studio10.0\vc\include\xxresult(28): error C2825: '_Fty': must be a class or namespacewhen followed by '::'
1> c:\program files\microsoft visual studio 10.0\vc\include\xxresult(40) :see reference to class template instantiation'std::tr1::_Result_type2<__formal,_Fty,_Arg0,_Arg1>' being compiled
1> with
1> [
1> __formal=false,
1> _Fty=__w64 unsigned int,
1> _Arg0=std::tr1::_Nil &,
1> _Arg1=std::tr1::_Nil &
1> ]
1> c:\program files\microsoft visual studio 10.0\vc\include\xxresult(597) :see reference to class template instantiation'std::tr1::_Result_of2<_Fty,_Farg0,_Farg1>' being compiled

等等,xxresult是\microsoft visual studio 10.0\vc\include\中的文件,肯定沒有錯誤,但是什麼原因引起的呢?

其實是這樣的,由於在VS2010Winsock bind()TR1C++ Technical Report 1)的bind()衝突導致的。在VS2010中微軟將TR1中的bind()聲明在名稱空間 std 中,而Winsockbind()則聲明在全域(global namespace),當在代碼中使用“using namespace std ”這樣的語句引入整個名稱空間後,由於此時存在兩個bind(),且TR1bind()是一個模板在編譯器重載解析時具有較高的優先級,直接調用bind()將導致了TR1Winsock調用的覆蓋,接下來在編譯階段的類型錯誤就不足爲怪了。
解決的方法很簡單,只要讓編譯器能夠正確區別兩者就可以了。爲了解決由於使用"using namespace std"帶來的衝突,我們需要在全域調用時顯式的聲明,如 “::bind()”,這樣編譯器就只會在全域中解析該函數的調用,而不會導致衝突。以後遇到類似的情況,都可以通過全域聲明(::call())來解決。

所以CCV1.5中的ofxTCPManager.cpp中的if(bind(m_hSocket,(struct sockaddr*)&local,sizeof(local)))改爲if(::bind(m_hSocket,(struct sockaddr*)&local,sizeof(local)))

ofxUDPManager.cpp中的int  ret     =bind(m_hSocket,(struct sockaddr*)&saServer,sizeof(structsockaddr));改爲int  ret   = ::bind(m_hSocket,(struct sockaddr*)&saServer,sizeof(structsockaddr));這個bind()函數前不加::時,在vs2008環境下編譯時不會有錯的

      修改後繼續編譯,然後又提示錯誤:

PocoFoundationmtd.lib(Exception.obj): error LNK2019: 無T法¤¡§解a析?的Ì?外ªa部?符¤?號? "__declspec(dllimport) public: __thiscallstd::basic_string<char,struct std::char_traits<char>,classstd::allocator<char> >::basic_string<char,structstd::char_traits<char>,class std::allocator<char> >(structstd::basic_string<char,struct std::char_traits<char>,classstd::allocator<char> >::_Has_debug_it)"(__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z),ê?該?符¤?號?在¨²函¡¥數ºy "protected: __thiscallPoco::Exception::Exception(int)" (??0Exception@Poco@@IAE@H@Z) 中D被À?引°y用®?

openframeworksLibDebug.lib(ofAppGlutWindow.obj): error LNK2001: 無T法¤¡§解a析?的Ì?外ªa部?符¤?號? "__declspec(dllimport) public: __thiscallstd::basic_string<char,struct std::char_traits<char>,classstd::allocator<char> >::basic_string<char,structstd::char_traits<char>,class std::allocator<char> >(structstd::basic_string<char,struct std::char_traits<char>,classstd::allocator<char> >::_Has_debug_it)"(__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)

openframeworksLibDebug.lib(ofUtils.obj): error LNK2001: 無T法¤¡§解a析?的Ì?外ªa部?符¤?號? "__declspec(dllimport) public: __thiscallstd::basic_string<char,struct std::char_traits<char>,classstd::allocator<char> >::basic_string<char,structstd::char_traits<char>,class std::allocator<char> >(structstd::basic_string<char,struct std::char_traits<char>,classstd::allocator<char> >::_Has_debug_it)"(__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z)等等。

       我在論壇上的這篇帖子看到,說要將整個OpenFrameworks用vs2010編譯一遍。我就將整個OpenFrameworks編譯了,注意,編譯之前同樣要像第一次編譯CCV時配置一下工程文件,配置無誤後再編譯。繼續編譯CCV1.5工程文件,又提示一些錯誤,後面的錯誤基本就是說什麼外部函數無法解析之類的錯誤,這個錯誤主要是因爲爲了使用dll中的函數,相應的.h中的函數聲明與其相關的lib庫不對應,也就是編譯器無法識別lib中的函數,在提供的源代碼無誤的前提下這個是跟版本有關,於是我將靜態鏈接庫目錄和附加依賴項中的一部分vs2008版本設置成了vs2010版本,這個主要是根據錯誤提示來修改,提示哪個lib庫有問題,就對這個庫的版本進行修改,我所做的改動如下:

鏈接器->常規->附屬庫目錄..\..\..\libs\rtAudio\lib\vs2008改爲..\..\..\libs\rtAudio\lib\vs2010,..\..\..\libs\Poco\lib\vs2008改爲..\..\..\libs\Poco\lib\vs2010

輸入->附加依賴項..\..\..\addons\ofxOsc\libs\oscpack\lib\vs2008\oscpackd.lib改爲..\..\..\addons\ofxOsc\libs\oscpack\lib\vs2010\oscpackd.lib,

再編譯,運行,成功!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章