在64位Win7中利用一些64位库的开发程序有时会出现Undefined Reference(未定义的引用)这类的问题。
比如系统中安装了64位版本的MySQL,然后按照网上教程一步步配置C/C++的数据库程序开发环境,到最后编译链接通常都会出现Undefined Reference问题。另一个例子是使用64位的OpenNI2库来开发Kinect应用程序,通常也会遇到Undefined Reference问题。
Undefined Reference是链接阶段的错误,通常是因为项目中没有正确设置库的xxx.lib文件路径。但这里的问题是完全正确地配置了xxx.lib文件的路径,还是报Undefined Reference错误,让人摸不着头脑。
其实错误的根源还是项目属性的配置。Windows的Codeblocks、Visual Studio、QT Creator等IDE都有一个Build Target设置项,它通常为Win32-Debug/Release,这就是问题所在。
一个项目可以有多个Build Target,每个Build Target都是一套不同的项目属性配置,尤其是项目属性中关于编译链接部分的配置。当点击“构建”或者“生成”的时候,IDE就会使用当前活动的Build Target来编译一个项目。切换活动的Build Target就可以快速地为项目选择一套属性配置。大多数IDE中初始情况下至少都有两个Build Target:Win32 Debug和Win32 Release。其中Win32是平台,它说明生成的是32位windows程序。Debug和Release是两套不同的编译器配置,Debug生成的程序比较大,包含较多的的调试信息,通常在开发过程中使用,方便调试;Release生成的程序比较小,运行效率比较高,但不适合调试,通常是最终发布可执行程序的时候用。平时修改项目属性的时候如果没注意选择Build Target的话,通常都是Win32 Debug的那一套项目属性中做的修改,因为它是初始情况下项目的活动Build Target。如果IDE允许,还可以新建自己的Build Target,用以生成其它平台的程序和设置不同的编译器选项。
所以这里的问题就很明白了。这里使用的库是64位版本的,库中的lib文件自然也是对应于64位平台的,但是项目的Build Target由于没有额外设置,默认为Win32平台,64位库无法与它兼容,这就导致即使项目属性中已经正确地设置了lib文件的路径,还是会提示Undefined Reference错误。
解决的方法很简单,但前提是所使用的IDE或者编译器支持64位的Build Target。
VS2013中支持的平台有Win32、X64和ARM,预定义的配置有Debug和Release,也就是说这里的Build Target一共至少可以有3x2=6种组合。设置64位平台的具体步骤如下:
在生成菜单中打开配置管理器:
可以看到初始情况下C++项目的平台只有Win32:
这里需要说明一下这个配置管理器的管理逻辑,不熟悉VS的可能看下面的解释比较吃力,如果赶时间可以暂时不用理会,直接按下一步操作。
最上面一行有“活动解决方案配置”和“活动解决方案平台”,而下面每一个项目都有一个自己的“配置”和“平台”,也就是说整个解决方案有Build Target,每个项目也有Build Target。所谓解决方案的Build Target,就是指解决方案中所有项目之间不同Build Target的组合。比如说,项目1设置为Win32 Debug,项目2也设置为Win32 Debug,这算是一个解决方案Build Target;项目1设置为Win32 Release,项目2仍然设置为Win32 Debug,这又是一个解决方案Build Target。前面计算过VS中一个项目可以有6种Build Target,那么对于两个项目的解决方案来说,可以有6x6=36种Build Target。
可以看到最上面第一行解决方案的配置和平台有“活动”两个字,意思很明显,选择活动的Build Target就是在这里,而且是为整个解决方案选择活动的Build Target。所以在VS中,不能单独切换某个项目的Build Target,只能切换整个解决方案的Build Target。
在活动解决方案平台中选择新建,在弹出的对话框中,从下拉列表选择平台为x64,选择复制Win32设置,勾选“创建新的项目平台”: