最近承载鞍项目需要打包程序安装到工控机上运行调试,但是在现场调试时出现了程序运行过程中崩溃的问题。
首先,项目程序用到的库包括qt、opencv、pcl、vtk。这些库用到的动态库文件分别从各自安装目录下的相关bin文件夹中找到,路径分别是:
opencv:
E:\builds\opencv_contrib330\x86\vc12\bin;
pcl:
E:\builds\PCL\PCL1.8.0\bin;
注意,在pcl的目录下的3rdparty文件夹中,也有几个动态链接库,不过在这个项目程序中不需要添加这些dll。
vtk:
E:\builds\PCL\VTK8\bin;
qt:
qt的动态库只用到了其中的几个,所在地址为D:\QT\5.7\msvc2013\bin。用到的几个qt动态库文件为:Qt5Cored.dll、Qt5Guid.dll、Qt5Networkd.dll、Qt5Widgetsd.dll。(生成的exe是debug版本的)。
除了qt的这几个dll之外,还需要将qt目录中:D:\QT\5.7\msvc2013\plugins 这一路径下的platform文件夹整个复制到exe的路径中。
将上述的dll文件添加到exe所在的路径下后,一般还会提示缺少一些dll文件。比如openni2.dll(应该是pcl相关的)、hidapi.dll(投影仪相关的)、msvcp120d.dll、msvcr120d.dll、msvcp140d.dll、vcruntime140d.dll(vc相关的)、TIS_UDSHL11.dll(相机相关的)、ucrtbased.dll。将这些dll再添加到exe的路径下面,程序界面就可以打开了。
一般情况下,对于没什么骚操作的程序,添加上述的dll就可以正常运行了。
但是在我打包好装到项目公司那边的工控机上调试时,却发现程序在数据处理过程中会崩溃从而自动退出。
后来经过分析,我怀疑是程序中pcl点云滤波部分的问题,于是在点云滤波位置的前后各加了一句输出文件的操作,发现程序确实是在pcl滤波处崩溃(运行程序只输出了在滤波操作前的那个txt文件)。注:这种对exe程序调试寻找问题的操作好像可以通过添加日志的方式进行,这个“日志”具体是什么意思、怎么操作,目前还没有了解过,不过应该比我这样“试一试”的方法靠谱点。
发现问题在pcl点云滤波的操作处,自然想到了将pcl的相关库文件再查一遍,看有没有漏掉。于是就将之前运行程序没有提示过的3rdparty中的dll加到了exe文件路径下,但是问题依然没有解决。
怀疑是系统环境的问题,于是换了几台电脑试过。最后发现,在装有vs的电脑上,程序运行是没有问题的,在没有装vs的电脑上,就会出现崩溃的问题。
于是,查了一下打包exe程序需要添加哪些vs的库文件。最后就找到了vs安装目录下的D:\VS2013\VC\redist,redist译为再发行包,其中包含了在没有vs的系统环境下vc程序运行可能用到的动态链接库。上面提到的msvcp120d.dll、msvcr120d.dll在这里面就有包含。因为是debug版本的,所以找到该路径下Debug_NonRedist文件夹,根据项目程序是32位,找到对应的x86文件夹下,有如下图所示的四个文件夹
其中第一个文件夹里面的就是msvcp120d和msvcr120d;第二个根据名字CXXAMP,百度了一下应该是对应着vc的所谓 Accelerated Massive Parallelism加速大规模并行机制的相关库文件;第三个显然是MFC所用到的库文件;第四个openmp百度了一下大概是vc中多核编程机制所用到的库文件。
将这几个文件夹中的dll加到exe路径下,发现当把openmp中的dll文件加进去时,程序便可以正常运行不会崩溃了。分析了一下原因,大概是pcl的滤波操作应该是用到了C++的多核编程机制,所以需要openmp中的对应dll文件。
以后为了稳妥,在打包的时候可以直接把该目录下的四个文件夹中的dll都加进去,即保证vc运行库的不缺失。