(一)安装Ceres库                

        1.用vcpkg安装Ceres库

                1.1.安装vcpkg

1.2.安装Ceres

1.3.配置Ceres

2.用Virtual Studio安装Ceres库

2.1.下载ceres-windows

2.2.打开或升级解决方案

2.3.编译项目libglog_static

2.4.编译项目ceres_static和ceres

2.5.编译例程

2.6.深入理解编译链接过程

3.用CMake安装Ceres库

(二)调用Ceres库

(三)发布应用程序

-----------------------------

PS:如有任何技术问题可加QQ群(117698356)或者我的微信(robot4xiihoo)一起交流

Ceres 翻译为谷神星,是太阳系中的一颗矮行星,于1801年被意大利神父 Piazzi 首次观测到,但随后 Piazzi 因为生病,跟丢了它的运行轨迹。几个月后,德国数学家 Gauss,利用最小二乘法,仅仅依靠 Piazzi 之前观测到的12个数据,便成功的预测了谷神星的运行轨迹。

两百多年后,为了解决一些复杂的最优化问题 (如:带边界约束的非线性最小二乘、一般的无约束最优化等),谷歌开发了一个 C++ 库 Ceres Solver。之所以取名 Ceres Solver,是为了纪念 Gauss 利用最小二乘法,成功的预测了谷神星轨迹,这个在最优化、统计学、天文学历史上,都具有重要意义的事件。

在谷歌内部,Ceres 已经被应用于多个产品中,如:谷歌街景中汽车、飞行器的位姿估计;PhotoTours 中 3D 模型的建立;SLAM 算法 Cartographer 等。此外,一些公司和研究所也在使用 Ceres,像是 Southwest Research Institute 的机器人视觉系统标定,OpenMVG 的光束平差 (BA) 问题,Willow Garage 的 SLAM 问题等。

我一个搞SLAM的,一直都是在Linux系统上安装和使用Ceres库,不管我是apt install还是下载源码后用CMake自己编译都相当简单。可是最近有个项目需要在windows系统上安装和使用Ceres库,发现在windows上安装和使用Ceres库比在Linux上复杂很多。写这篇博客就是记录我踩过的各种坑,希望对后来的人起到帮助作用。

(一)安装Ceres库

安装Ceres库,我推荐直接看官方的教程(http://ceres-solver.org/installation.html),讲的很详细。官方给出了在windows系统上安装Ceres库的3种方法:

  • 用vcpkg安装Ceres库。
  • 用Virtual Studio安装Ceres库。
  • 用CMake安装Ceres库。

用vcpkg安装Ceres库非常简单,几乎是一键安装,但缺点是不能手动选择Ceres及其依赖的版本,另外一些编译选项也不能修改。后面应用中要对编写选项做修改,显然vcpkg方式不能满足要求。用Virtual Studio安装Ceres库,就是在Virtual Studio中新建C++工程,然后将从网上下载的Ceres及其依赖的源码放入刚新建C++工程的对应位置,然后编译这些C++工程生成我们需要的Lib静态库和Dll动态库。这种方式可以手动选择Ceres及其依赖的版本,也能修改编译选项。用CMake安装Ceres库,相比于用Virtual Studio安装Ceres库,优点是只需基于CMake工程就能编译很轻量且移植性好,但缺点就是配置过程很复杂。所以,我这里推荐用Virtual Studio安装Ceres库。

1.用vcpkg安装Ceres库

vcpkg是微软C++团队开发的适用于C和C++库的跨平台开源软件包管理器,它大大简化了 Windows、Linux和macOS上第三方库相关的下载和配置操作,目前已有超过1600个第三方库可以通过vcpkg来安装。vcpkg其实就是类似于Linux的apt包管理器和Python的pip包管理器的东西。

1.1.安装vcpkg

关于vcpkg的安装和使用,在Windows系统上安装vcpkg其实官方教程(https://github.com/microsoft/vcpkg/blob/master/README_zh_CN.md)已经很详细了,我这里简单再说一说。首先是下载vcpkg安装包到我们的windows电脑,然后就是运行安装包就可以了。首先在你的windows电脑安装Git客户端,然后用Git下载vcpkg安装包;如果没有装Git也不要紧,就直接去vcpkg的github下载安装包然后安装是一样的。

  • Git客户端的下载地址:https://git-scm.com/downloads
  • vcpkg安装包的下载地址:https://github.com/microsoft/vcpkg

这里假设已经有Git的情况,以管理员身份直接打开你的windows电脑的CMD命令终端,输入下面的命令进行vcpkg的安装即可:

> git clone https://github.com/microsoft/vcpkg
> .\vcpkg\bootstrap-vcpkg.bat

1.2.安装Ceres

继续在CMD命令终端,使用以下命令安装你所需要的C/C++库,关于vcpkg的具体用法,可以使用帮助命令vcpkg help查看教程,这里先用vcpkg search命令查询我们要安装的ceres包的情况:

> CD vcpkg\vcpkg
> vcpkg search ceres

从上面的查询结果看,vcpkg仓库中的ceres版本为2.1.0,另外还有ceres的其他版本(比如ceres[cuda]、ceres[cxsparse]等)。另外vcpkg中的包分32位和64位两种,默认是装32位。如果想同时在32位和64位应用中使用这个包,就要两种都装上:

#安装ceres 32位版本的命令
> vcpkg install ceres
#安装ceres 64位版本的命令
> vcpkg install ceres:x64-windows

上面直接安装的ceres版本,在进行优化迭代时是使用的DENSE_QR求解方法。而ceres[cxsparse]、ceres[suitesparse]、ceres[eigensparse]等版本是非必需项,如果安装了这些版本的话,在进行优化迭代时是使用的SuiteSparse或CXSparse或Eigen的稀疏Cholesky分解选项的SPARSE_NORMAL_CHOLESKY求解方法。对于求解的问题矩阵比较稀疏时,后者的求解效率显然比前者要高。所以可以根据需要,选择是否安装这些非必须版本,安装方法如下:

#安装ceres 32位版本的命令
> vcpkg install ceres[cxsparse] --recurse
> vcpkg install ceres[suitesparse] --recurse
> vcpkg install ceres[eigensparse] --recurse
#安装ceres 64位版本的命令
> vcpkg install ceres[cxsparse]:x64-windows --recurse
> vcpkg install ceres[suitesparse]:x64-windows --recurse
> vcpkg install ceres[eigensparse]:x64-windows --recurse

最后在安装完成以后,我们用vcpkg list命令查看已安装的包,可以发现ceres包安装的同时其相应的依赖(比如Eigen、glog、gflags等)也被自动安装了。

1.3.配置Ceres

虽然上面已经安装好了Ceres库,但是我们自己编写C++程序调用Ceres库时,需要在我们的程序中配置Ceres库所涉及的include和lib目录以及一些链接属性指定,这样很不方便。下面讨论几种情况下,配置Ceres的方法。我这里使用的是win10+VS2022的环境,其他版本环境也是类似的。

(1)Visual Studio中的非CMake项目使用Ceres库的配置

在Visual Studio中新建的C++项目默认是非CMake项目,我们可以将vcpkg中已安装的所有库配置到Visual Studio的全局范围上,这样vcpkg中已安装的各个库就像C/C++系统标准库那样,我们可以在Visual Studio中的任何新建C++项目中直接通过#include <xxx>的方式即可调用,而无需做额外的配置。将vcpkg中的库配置到Visual Studio全局范围上的方法,如下命令所示:

#将vcpkg安装到Visual Studio全局范围
> vcpkg integrate install
#将vcpkg从Visual Studio全局范围卸载
> vcpkg integrate remove

有时候可能要在不同的项目中使用一些库的不同版本,那么就不能将vcpkg配置到Visual Studio全局范围。这个时候可以将vcpkg打包到nuget,然后在Visual Studio的具体某个项目中通过nuget方式加载vcpkg中的库,这样灵活性就很高。如果vcpkg相应库的版本不是我们项目想要的,该项目就可以不加载vcpkg,而是通过手动方式安装和配置这个库。将vcpkg中的库配置到Visual Studio局部范围上的方法,如下命令所示:

> vcpkg integrate project

接着打开Visual Studio,在菜单栏中依次点击:工具->NuGet包管理器->程序包管理器设置,在设置界面找到“程序包源”,将vcpkg添加进去。名称栏随便填,我这里填的vcpkg,方便后面用的时候好找。源栏,填上面命令执行后生成的文件的路径,比如C:\<替换成你实际的路径>\vcpkg\vcpkg\scripts\buildsystems。最后,点击确定就可以了。

如果想要在Visual Studio解决方案的某个项目中使用vcpkg中的包,只需要在该项目中用nuget安装vcpkg就可以了,比如下面这样。如果后面不需要了的话,点击卸载就可以了。

(2)Visual Studio中的CMake项目使用Ceres库的配置

在Visual Studio中新建的C++项目默认是非CMake项目,也就是说这个C++项目是依赖于*.sln或*.vcxproj工程文件的,也就是说不能脱离Visual Studio的开发环境。而Visual Studio中新建的CMake C++项目,是不依赖于*.sln或*.vcxproj工程文件的跨平台C++项目。如果要在Visual Studio中的CMake C++项目中使用Ceres库,打开该项目的CMake设置选项,将vcpkg toolchain文件路径加在CMake toolchain file 中,如下:

[vcpkg root]/scripts/buildsystems/vcpkg.cmake

(3)非Visual Studio中的CMake项目使用Ceres库的配置

如果要在非Visual Studio开发环境的CMake C++项目中使用Ceres库,那么在用CMake命令编译项目时,需要使用如下工具链文件进行命令配置:

> cmake -B [build directory] -S . "-DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake"
> cmake --build [build directory]

另外在CMake中,仍需通过find_package来使用vcpkg中已安装的库。

2.用Virtual Studio安装Ceres库

用vcpkg安装Ceres库虽然简单,但是灵活性很差。所以,我这里选择灵活性更好的方法,用Virtual Studio安装Ceres库,就是在Virtual Studio中新建C++工程,然后将从网上下载的Ceres及其依赖的源码放入刚新建C++工程的对应位置,然后编译这些C++工程生成我们需要的Lib静态库和Dll动态库。这种方式可以手动选择Ceres及其依赖的版本,也能修改编译选项。

2.1.下载ceres-windows

如果大家不知道怎么在Virtual Studio中新建C++工程然后配置和编译Ceres源码的话,可以去官方教程下载现成的Virtual Studio工程,下载地址如下:

  • Ceres-windows工程下载:https://github.com/tbennun/ceres-windows

我们可以发现,上面刚刚下载来的ceres-windows文件夹里面其实就是个模板,里面的ceres-solver、Eigen、glog文件夹都是空的。因此我们还要单独去将ceres-solver、Eigen、glog的源码都下载过来,然后再解压放到ceres-windows里面的对应文件夹中。我这里下载的源码版本如下:

  • ceres-solver-1.12.0下载地址:https://github.com/ceres-solver/ceres-solver/tags
  • Eigen-3.4.0下载地址:https://gitlab.com/libeigen/eigen/-/releases
  • glog-0.3.5下载地址:https://github.com/google/glog/tags

2.2.打开或升级解决方案

可以发现ceres-windows文件夹里面有3个解决方案文件:ceres-2010.sln、ceres-2012.sln、ceres-2015.sln。选择与你电脑上Virtual Studio版本对应的解决方案打开即可,如果你的Virtual Studio版本高于2015版(比如我用的就是Virtual Studio 2022),那么直接打开ceres-2015.sln解决方案并按接下来的提示操作步骤完成解决方案版本的自动升级。

另外就是记得去解决方案属性中,将解决方案和各个项目的配置(Debug/Release)和平台(x64/Win32)设置成统一的模式,如果不统一的话后面编译会报错。我这里统一都设成了Release和Win32的模式,如下所示。

在正式开始编译之前,可以去解决方案属性中看一下各个项目之间的依赖关系。

可以发现我们这个解决方案下的各个项目之间的依赖关系,其中项目libglog_static不依赖别的项目,项目libglog_static就是用于创建静态C++库Lib的项目。而项目ceres_static和ceres都依赖于项目libglog_static,项目ceres_static是用于创建静态C++库Lib的项目,项目ceres是用于创建动态C++库Dll的项目。其他项目(curve_fitting、curve_fitting_c、ellipse_approximation、helloworld、helloworld_analytic_diff、helloworld_numeric_diff、helloworld_static、robust_curve_fitting、simple_bundle_adjuster)则都是例程,它们依赖于ceres_static或者ceres。具体依赖关系,如下:

通过项目之间的依赖关系可知,我们需要先编译项目libglog_static,然后编译项目ceres_static和ceres,最后编译例程项目(curve_fitting、curve_fitting_c、ellipse_approximation、helloworld、helloworld_analytic_diff、helloworld_numeric_diff、helloworld_static、robust_curve_fitting、simple_bundle_adjuster)。

2.3.编译项目libglog_static

直接选中项目libglog_static,然后点击右键,在弹出来的菜单列表中选择“生成”就开始编译了。编译完成后,按照项目属性中配置的输出路径,编译生成的静态库文件libglog_static.lib存放在路径“<你的解决方案文件夹>\Win32\Release\”。

2.4.编译项目ceres_static和ceres

跟上面一样,直接选中项目,然后点击右键,在弹出来的菜单列表中选择“生成”就开始编译了。编译完成后,按照项目属性中配置的输出路径,项目ceres_static和ceres编译生成的静态库文件ceres_static.lib和动态库文件ceres.dll依然存放在路径“<你的解决方案文件夹>\Win32\Release\”。到这里,待会例程中需要用到的库文件libglog_static.lib、ceres_static.lib、ceres.dll就都准备好了。

2.5.编译例程

解决方案中的其他项目(curve_fitting、curve_fitting_c、ellipse_approximation、helloworld、helloworld_analytic_diff、helloworld_numeric_diff、helloworld_static、robust_curve_fitting、simple_bundle_adjuster)则都是例程,也就是用来供大家测试ceres库的,看ceres库编译安装是否正确。

(1)编译例程helloworld

直接选中项目,然后点击右键,在弹出来的菜单列表中选择“生成”就开始编译了。不过编译会遇到“C4996”的错误,如下:

解决办法是需要在项目属性设置中添加宏,配置属性>C/C++>预处理器>预处理器定义,然后在里面追加填入如下的宏:

_CRT_NONSTDC_NO_DEPRECATE

然后“重新生成”就可以了,编译成功后会生成可执行文件helloworld.exe。按照项目属性中配置的输出路径,编译生成的可执行文件helloworld.exe存放在路径“<你的解决方案文件夹>\Win32\Release\”。直接双击helloworld.exe就可以执行这个例程并看到运行输出结果了。不过控制台会一闪而过,这是因为程序运行完就立马退出了。可以在Virtual Studio中运行这个例程,就不会闪退了。也就是在Virtual Studio中选中项目helloworld,然后右键>调试>启动新实例,运行结果如下:

(2)编译例程helloworld_static

与上面一样,编译会遇到“C4996”的错误,解决办法是需要在项目属性设置中添加宏,如下:

_CRT_NONSTDC_NO_DEPRECATE

然后“重新生成”就可以了,编译成功后会生成可执行文件helloworld_static.exe。按照项目属性中配置的输出路径,编译生成的可执行文件helloworld_static.exe存放在路径“<你的解决方案文件夹>\Win32\Release\”。直接双击helloworld_static.exe就可以执行这个例程并看到运行输出结果了。不过控制台会一闪而过,这是因为程序运行完就立马退出了。可以在Virtual Studio中运行这个例程,就不会闪退了。也就是在Virtual Studio中选中项目helloworld,然后右键>调试>启动新实例,运行结果跟上面是一样的。

这里说一下helloworld和helloworld_static这两个项目的区别,

2.6.深入理解编译链接过程

为了保证我们自己开发的程序在发给用户使用时能具有较好的兼容性,程序开发过程有很多设置项需要注意,这里就结合上面的helloworld和helloworld_static这两个项目来深入探讨一下程序在编译和链接的完整过程。

(1)配置与平台选择的统一性

记得去解决方案属性中,将解决方案和各个项目的配置(Debug/Release)和平台(x64/Win32)设置成统一的模式,如果不统一的话后面编译会报错。我这里统一都设成了Release和Win32的模式。

其实Debug和Release编译出来的*.exe可执行文件都是可以正常运行的,Debug编译出来的程序会被加入一些跟调试相关的东西,所以Debug版本的程序文件会大一些,当然Debug版的程序在运行效率上也比Release的低。所以,一般在正式发布软件程序时都是Release版的。

而x64和Win32是跟运行程序的硬件平台有关系,我们知道计算机的CPU有32位和64位两种,相应的操作系统也就有32位操作系统和64位操作系统。Win32对应的就是32位操作系统,x64对应的就是64位操作系统。一般来说,32位操作系统只能运行Win32程序,64位操作系统既能运行x64程序也能运行Win32程序。对于用户来说,使用64位操作系统兼容性更高。而对于程序开发者来说,开发Win32程序兼容的机器更多。

(2)运行库模式的统一性

多线程MT编译出来的文件体积要比多线程MD编译出来的大,因为MT是把对应的运行时库直接放到编译出来的PE文件当中,而MD却是运行的时候从第三方dll中获取运行时库,自己本身却不包含。多线程MT编译出来的文件运行时不需要加载第三方dll所以运行效率要比多线程MD稍微高一点点,当然作为用户是完全感觉不到的。

目前市面上大部分的软件都使用的是多线程MD的方式,编译出来的文件小,所有运行时库统一,同时也让内存管理简单化,省去了跨模块内存访问带来的各种bug。目前市面上大部分的软件都使用的是多线程MD的方式,编译出来的文件小,所有运行时库统一,同时也让内存管理简单化,省去了跨模块内存访问带来的各种bug。

在工程属性窗体中选择配置属性,C++选项的代码生成多线程调试 DLL (/MDd)和多线程调试 DLL (/MTd)是Debug版本,后面没有d的是Release版本。多线程MT加载的是静态运行时库,属于C语言版本。而多线程MD版本加载是动态运行时库,属于微软版本。不管你选择哪种运行库模式,你的项目及其依赖的库项目的这个模式要统一,比如你的项目helloworld设的模式是MD,那么其依赖库ceres和libglog_static的模式也要是MD。没有特殊情况,统一都使用默认的模式MD就行了。

(3)动态库与静态库

静态库而言,函数和数据被编译进一个二进制文件(通常扩展名为.lib)。在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其他模块组合起来创建最终的可执行文件(.exe文件)。当发布产品时,只需要发布这个可执行文件,并不需要发布被使用的静态库。

在使用动态库的时候,编译后往往提供两个文件:一个引入库(.lib)文件(也称“导入库文件”)和一个DLL(.dll)文件。当然到了后面会告诉你如果只提供一个DLL文件,使用显示连接的方式也可以调用,只是稍加麻烦而已。虽然引入库的后缀名也是“lib”,但是,动态库的引入库文件和静态库文件有着本质的区别。对一个DLL文件来说,其引入库文件(.lib)包含该DLL导出的函数和变量的符号名,而.dll文件包含该DLL实际的函数和数据。在使用动态库的情况下,在编译链接可执行文件时,只需要链接该DLL的引入库文件,该DLL中的函数代码和数据并不可复制到可执行文件,直到可执行程序运行时,才去加载所需的DLL,将该DLL映射到进程的地址空间中,然后访问DLL中导出的函数。这时,在发布产品时,除了发布可执行文件以外,同时还需要发布该程序将要调用的动态链接库。

静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,lib静态库中的指令都全部被直接包含在最终生成的exe文件中了。但是若使用DLL动态库,该DLL不必被包含在最终exe文件中,exe文件执行时可以“动态”地引用和卸载这个与exe独立的DLL文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。

以前面的例程项目helloworld和helloworld_static来具体说明动态库和静态库的链接过程,首先是静态库libglog_static.lib分别被静态链接到了静态库ceres_static.lib和动态库ceres.dll。也就是说ceres_static.lib和ceres.dll都已经包含进了libglog_static.lib的全部内容,再发布ceres_static.lib和ceres.dll库时就不再需要附带libglog_static.lib。静态库ceres_static.lib又被静态链接到了应用程序helloworld_static.exe,也就是说helloworld_static.exe已经包含进了ceres_static.lib的全部内容,我们在发布程序时只需要把helloworld_static.exe拷贝给客户就可以了。而动态库ceres.dll被动态链接到了应用程序helloworld.exe,也就是说helloworld.exe运行时才会去动态链接ceres.dll,那么我们在发布程序时就要将helloworld.exe和ceres.dll一起拷贝给客户。如果只拷贝helloworld.exe给客户,那么程序运行时会报错找不到ceres.dll。

(4)系统级的运行时支持

上面讨论的情况中,静态库lib、动态库dll和应用程序exe其实都要依赖于系统级的运行时(RunTime)支持。对于运行在Windows系统上的任何C++程序,都要依赖于系统的C++运行时库(Microsoft Virtual C++)。而对于运行在Windows系统上的任何基于.NET的程序(比如WPF、Winform等),都要依赖于系统的.NET运行时库(.NET Framework)。

因为我们上面讨论的程序都是C++程序,这里主要讨论Windows系统的C++运行时库。我亲测了一下,无论是win7还是win10,在装系统后或者系统自动更新后,C++运行时库(Microsoft Virtual C++)都会自动装上,如下所示。

首先我们要知道Virtual C++有很多版本,并且高版本不一定向下兼容(比如某个程序依赖于Virtual C++ 2010,你电脑如果只安装了Virtual C++ 2012可能就无法运行)。因此,电脑中一般都会将目前所有受支持的Virtual C++ 版本全部装上,包括2005/2008/2010/2012/2013/2015-2022这些版本,其中2015-2022版本囊括了2015版及以后的各个版本。另外就是Virtual C++版本还分32位(x86)和(x64),在64位的windows系统中Virtual C++的x86和x64版本都会装,而32位的windows系统中只会装Virtual C++的x86版本。

在一些特殊情况下,有的电脑上可能没有装Virtual C++,或者Virtual C++的版本不全。那么我们发给客户的程序(比如helloworld_static.exe、或者helloworld.exe+ceres.dll)可能就会报错说丢失MSVCP140.dll,比如:

最直接的解决办法,就是去下载对应版本的Virtual C++安装到你的电脑。一般我们使用哪个版本的Virtual Studio开发环境开发这个C++程序,那么这个C++程序就基于这个版本的Virtual Studio所集成的Virtual C++。可以去项目的属性页查看平台工具集具体版本,Virtual Studio各版本对应的工具集版本号如下:

-Visual Studio 2022: V143

-Visual Studio 2019: V142

-Visual Studio 2017: V141

-Visual Studio 2015: V140

-Visual Studio 2013: V120

-Visual Studio 2012: V110

-Visual Studio 2010: V100

-Visual Studio 2008: V90

-Visual Studio 2005: V80

-Visual Studio 2003: V71

-Visual Studio 2002: V70

-Visual Studio 6: V60

如果你不知道缺哪个版本的Virtual C++,就把所有Virtual C++版本全装一遍。Virtual C++安装包可以去微软官网下载(https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170),安装包是一个VC_redist可执行文件,运行后会在线去安装对应版本的Virtual C++。如果手动一个个去下载Virtual C++的各个版本闲麻烦,可以去这里(https://www.itechtics.com/microsoft-visual-c-redistributable-versions-direct-download-links/)打包下载Virtual C++所有版本。

但对于不懂技术的普通用户来说,手动去安装Virtual C++太复杂了,并且有时候我们的C++程序还可能依赖额外的MFC或ATL之类的库,因让用户手动去装这些依赖不现实。其实我们在编译我们的项目时,可以将属性页中的“将C++运行时复制到输出目录”设置为“是”。

那么在编译项目后,编译输出目录中除了生成我们自己写的exe和dll文件外,还生成了大量系统级的dll文件。我们只需要将这些系统级的dll和我们自己的exe和dll文件全部拷贝给客户,客户那边电脑不管有没有装系统级的运行时环境就都可以正常使用程序了。

3.用CMake安装Ceres库

如果你不使用Virtual Studio开发环境做开发的话,那你就要用CMake手动一步一步去配置和编译Ceres及其依赖的源码。具体步骤比较繁琐,大家直接去看Ceres的官方教程吧:

http://ceres-solver.org/installation.html

参考文献

[1] 张虎,机器人SLAM导航核心技术与实战[M]. 机械工业出版社,2022.

在windows系统中使用Ceres非线性优化库:(一)安装Ceres库相关推荐

  1. 如何将USBKey中的证书注册到Windows系统中、分享一个 证书 C++安装

    USBKey 是一种 USB 接口的硬件设备.如坚石诚信的 ET199Auto ,内置 16 位国外进口高性能智能卡芯片,有一定的存储空间,可以存储用户的私钥以及数字证书,利用 USBKey内置的RS ...

  2. 在Windows系统中配置Google AddressSanitizer

    Google AddressSanitizer简介 AddressSanitizer (ASan) 是 C 和 C++ 的内存错误检测软件,它可以检测: 释放指针后继续使用 堆缓冲区溢出 栈缓冲区溢出 ...

  3. windows系统中创建线程常用哪几个函数,有什么区别?

    windows系统中创建线程常用哪几个函数? 在windows系统中创建线程的函数有: CreadThread,AfxBeginThread,_beginthread,_beginthreadex. ...

  4. 在windows系统中安装Sulley

    在windows系统中安装Sulley 我是在win10的64位系统下面完成本次安装的,具体教程如下,需要安装的库和工具比较多,需要耐心处理各种问题. 需要的文件打包下载: 链接: https://p ...

  5. 【从零学习OpenCV 4】Windows系统中安装OpenCV 4

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...

  6. Windows系统中哪些文件夹可以删除

    Windows系统中哪些文件夹可以删除 windows文件夹中的哪些文件可以删除 经过以下的设置后,你的系统会更加清爽.简洁.高效! 1.打开"我的电脑"-"工具&quo ...

  7. 在windows系统中使用GDAL

    在windows系统中使用GDAL 啥是GDAL windows 安装GDAL osgeo4w 安装 osgeo4w 使用.py指令 python GDAL库安装 参考 啥是GDAL GDAL 官网 ...

  8. Windows系统中svn服务端下载和搭建

    Windows系统中svn服务器下载和搭建 svn服务器下载地址:Download | VisualSVN Server 1. svn服务器下载 (1) 请求svn服务器下载地址(Download | ...

  9. windows系统中Linux用法

    Linux是什么?一种操作系统,多用户.多任务 安装gitforwindows实现部分Linux命令:Windows系统中可以实现上百个Linux命令,但无法安装Linux软件 在图形界面打开term ...

最新文章

  1. 如何在实际中计划和执行一个机器学习和深度学习项目
  2. [导入]将DataGrid输出到Excel文件
  3. 数据结构源码笔记(C语言):Huffman树字符编码
  4. SpringAOP中通过JoinPoint获取值,并且实现redis注解
  5. 【算法】剑指 Offer 22. 链表中倒数第k个节点
  6. Running pip as root will break packages and permissions. You should install packages reliably by usi
  7. l360清零软件无响应_爱普生Epson L360 清零软件
  8. matlab仿真放入直流电源,用Matlab/Simulink软件包建模电容滤波直流电源
  9. php模板开发教程,Destoon模板制作简明教程
  10. java渗透_java 渗透模型
  11. 2013年全国计算机一级上机,2013年全国高校计算机联合考试一级机试试题(1)
  12. 「应用安全」应用安全原则
  13. 【pytest】内置 fixtures 之 tmpdir:创建临时文件
  14. 诺贝尔奖得主费曼大神教你如何学习
  15. 牛逼哄哄的富士康老板郭台铭低头了,夏普将向三星供应液晶面板
  16. 【前端基础】20.JQuery基本语法
  17. 超有爱 超好记的 英文三字经 生个宝宝一起学吧
  18. windows系统下文件批量重命名方法
  19. 面试中常被问到(三)c/c++区别
  20. python练习-easygui-温度转换

热门文章

  1. 压测工具大比武!谁是市场主流?
  2. 家庭“非处方药”完全手册
  3. php安全漏洞怎么修复,PHP安全团队已发布安全补丁修复PHP 7中的高危漏洞
  4. RestTemplat
  5. Loki+Promtail+Grafana
  6. Java实现微信小程序授权手机号登陆(史上最简单)
  7. python 控制 手机来进行操作皇室战争要卡
  8. JVM刨根问底之程序计数器
  9. Angular10 + file-saver前端实现html导出word(包含图片)
  10. 智慧灯杆案例:四川眉山天府新区400盏智慧路灯建成投用