在之前的文章【环境配置】(四)opencv3中配置sfm模块已经说过如果配置ceres solver,这篇文章主要说下在使用ceres solver的时候遇到的问题。
1、使用ceres solver依赖于gflags,glog, Eigen3以及suitesparse,使用第一步首先要配置好相关的环境,include 和lib input
我的include配置如下:
E:\Opencv3\Ceres_Install\Ceres\include
E:\Opencv3\Ceres_Install\Eigen3\include\eigen3
E:\Opencv3\Ceres_Install\gflags\include
E:\Opencv3\Ceres_Install\glog\include
E:\Opencv3\Ceres_Install\suitesparse\include
lib配置如下:
包含路径:
E:\Opencv3\Ceres_Install\suitesparse\lib64\lapack_blas_windows
E:\Opencv3\Ceres_Install\Ceres\lib
E:\Opencv3\Ceres_Install\gflags\lib
E:\Opencv3\Ceres_Install\glog\lib
包含lib名称:
ceres.lib
gflags_nothreads_static.lib
gflags_static.lib
glog.lib
libblas.lib
liblapack.libshlwapi.lib(解决错误2加入)
以上是release下面的配置,debug模式下面包含路径已知,lib名称更换为:
glogd.lib
ceres-debug.lib
gflags_static_debug.lib
gflags_nothreads_static_debug.lib
libblas.lib
liblapack.lib
shlwapi.lib(解决错误2加入)
配置中遇到的问题以及解决方法
1、出现错误
error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl google::base::CheckOpMessageBuilder::CheckOpMessageBuilder(char const *)" (__imp_??0CheckOpMessageBuilder@base@google@@QEAA@PEBD@Z) referenced in function "class std::basic_string,class std::allocator > * __cdecl google::MakeCheckOpString(int const &,int const &,char const *)" (??$MakeCheckOpString@HH@google@@YAPEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBH0PEBD@Z)
原因在于报错信息是动态链接库中的函数信息有误;
解决方法:在项目->属性->c/c++->预处理器->预处理器定义中加入GOOGLE_GLOG_DLL_DECL=
参考:Ceres-Solver在VS2017下的配置
在这篇中还提到了与windows.h下定义的ERROR发生了冲突的问题,预处理器加上GLOG_NO_ABBREVIATED_SEVERITIES解决,我没有遇到这个错误。
这个错误在于glog使用静态链接发生的错误——
glog如何采用静态链接的方式呢?答案是要看官方doc文档的说法:在自定义工程中添加“GOOGLE_GLOG_DLL_DECL=” 和 “GLOG_NO_ABBREVIATED_SEVERITIES” 这两个宏,第二个宏主要是为了避免与windows.h冲突(下面会讲到),第一个宏才是使用静态链接库时必须的!在编译时可以编译两个版本:Release 和 Debug 以供调试时使用。
2、出现错误:
gflags_nothreads_static.lib(gflags.obj) : error LNK2019: unresolved external symbol __imp_PathMatchSpecA referenced in function "public: class std::basic_string,class std::allocator > __cdecl google::`anonymous namespa
上面错误是连接gflangs没有成功——直接#include
并链接上gflags.lib或gflags_nothreads.lib,应用程序可能并不能链接成功,出现上面的错误。解决办法是在input上加上下面这个lib的声明: shlwapi.lib
参考:Google开源命令行参数解析库gflags
3、其他类似错误的一般处理方式
遇到unresolved external symbol "__declspec(dllimport) public这种错误,可能的原因有:
(1)没有将相应的lib包含进去——检查lib有没有包含正确
(2)预处理器需要添加内容处理错误——这个错误的解决方式我自己找不到,不知道应该添加什么,一般都是上网找BUILDING_DLL
(3)可能是因为Unicode搞的鬼,Property Page-General-Charater set修改为Not set
(4)关于多线程的问题,详情参考VS2013编译报错——error LNK2001: 无法解析的外部符号 __imp_PathMatchSpecA E:\CaffeProgram\3train_mnist(p)\3train_mnist\gflags.lib(gflags.obj) 3train_mnist
错误详情参考:VC6.0 error LNK2001: unresolved external symbol _main解决办法
参考: 关于error LNK2001: unresolved external symbol "__declspec(dllimport) public
其他:ceres solver使用入门
参考:一文助你Ceres 入门——Ceres Solver新手向全攻略