使用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,

再编译,运行,成功!


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