目录
问题来源
一个32位工程,根据需求,需要换成64位平台,对应地,其所依赖的库也需要安装64位的。
当安装成功64位PCL并编译GridMap库后,将工程切换到64位平台并对环境完成相关配置,项目可以成功生成,但是运行却出现无法正常启动(0xc000007b)的错误:
问题分析过程及解决
这个表明程序是成功编译的,只是运行时出现错误,一般是运行时链接到了与exe位数不同的dll。
比如,64位的程序,运行时却链接到32位的dll,或者32位的程序,运行时链接到了64位的dll。
于是,我对用到的库仔细排查:
(1)PCL库,环境变量中已添加64位PCL及第三方库的bin路径;
(2)QT库,环境变量中也添加了64位QT库;
(3)GridMap库,为静态库,自然不用管。
用到的库都正确添加环境变量,不应该有错啊,于是开始百度。
第一个方法,安装DirectX9,虽然觉得应该没用,但还是安装了,果然没用。
第二个方法,排查msvc相关dll,搜索msvcp140.dll,其在system32文件夹中,并确认为64位,然后再找到安装VS2015带的这几个64位dll,直接复制到exe路径下,运行依然出错:
至此,实在无招了。
于是再查看vs输出信息 :
有两个可疑的信息:
(1)我的工程明明是x64,exe后面为什么显示Win32?
(2)我的64位PCL明明安装在 C:\Program Files 下,为什么会链接C:\Program Files (x86)的dll?
第一个问题,我检测了下,生成的exe确实是64位的,并且,新建了一个64位Qt工程,输出信息后面也是带Win32,虽然不知道为什么,但应该不是这个导致出错。
第二个问题,首先检查vs环境配置是否存在问题,查看后没有问题。然后,为了印证是否确实链接到C:\Program Files (x86)下32位的PCL库,我将C:\Program Files (x86)的PCL 1.8.1文件夹改为PCL 1.8.10,再次运行,让我大喜:
这就表明,这个64位exe,运行时确实链接的是32位的pcl库,并且,64位的直接没有找到,而且,这个dll是存在我加在环境变量中的一个路径下的。
这就很明显了,还是环境变量的问题。
于是,我有检查了一下环境变量,那几个路径都添加了,不会有问题啊,然后,我又想起是怎么添加这几个路径的:
很早之前,第一次安装PCL时,我在有道云笔记中记录了安装过程,并且对添加的东西有了一些总结,这次安装PCL,依然是找到当时记录的文档,安装成功后,直接将当时记录的要添加到环境变量中的路径进行修改,当时安装的是32位的,在C:\Program Files (x86)路径下,要添加的几个路径如下:
而我这次安装的64位,是在C:\Program Files下,这样只需要将这几个路径的(x86)删除,然后直接复制到环境变量Path中就可以了。
对,就是这么干的。
然后,根据刚才的排错,pcl_common_release.dll没有找到,但它实实在在就在C:\Program Files\PCL 1.8.1\bin路径下,并且,这个路径实实在在添加到Path环境变量中了。这可真是邪门哈。
于是,我在资源管理器中打开这个路径,复制地址栏,粘到有道云笔记中对比,如下:
好像这个路径结尾并没有对齐,但开头却是对齐的,于是挨个字母对照了一下,也完全一样,再细看,终于找到问题所在,Files与反斜杠之间竟然多了一个空格...
终于明白了,Program Files (x86)文件夹,Files与后面的括号是有空格的,我删除(x86)的时候,没有将空格删除...前两个路径有空格,后面三个路径没有空格,还是太粗心了。
总结
这个小小的空格真的是很隐蔽,不过所幸,从遇到错误,到找到错误,应该是不到两个小时吧。
这个错误的本质原因还是exe链接到了与自己本身位数不同的dll。