VS2019编译CCCoreLib库在QtCreator中的配置与应用
2026/9/20 14:05:13 网站建设 项目流程

简介:CCCoreLib 是 CloudCompare 的核心算法库,这份资源已用 VS2019 编译好 lib 与 dll,可直接集成到 QtCreator 工程中,适合点云处理开发者和算法研究者使用。包体共 102 个文件,以 h/cpp 源码为主体,覆盖最近邻搜索、距离计算、点云配准、分割与几何分析等常见模块,另含 pro/user 工程配置以及编译生成的 lib/dll,整体仅 567KB,轻量便于项目引入。目前已有 492 人学习下载,适合希望深入阅读源码、按需定制算法或快速在 Qt 环境搭建三维数据处理能力的开发者。通过这份资源可获得可链接的静态库、动态库和完整源码,既能直接调用封装好的功能,也能对照源码理解 CloudCompare 的底层实现,为二次开发和性能优化提供扎实基础;对研究点云处理算法的读者来说,也是不错的参考样本。 从CloudCompare里拆出来的CCCoreLib,是很多做点云处理的兄弟绕不开的一个基础库。这个标题看着简单,但里面其实藏了不少关键信息:VS2019编译器编译、lib和dll都有、要能在QtCreator工程里直接打开用。也就是说,你手里拿到的这套东西,是已经编译好的二进制产物,而不是要你自己再去折腾一遍源码构建。这篇博文就围绕这套编译产物,把怎么用它、怎么在QtCreator里配环境、踩过哪些坑,一次讲清楚。

1. 项目背景:CCCoreLib到底是什么,为什么大家要折腾它的编译产物

1.1 从CloudCompare剥离出来的核心算法库

CCCoreLib,全称是CloudCompare Core Library,最初是作为开源点云处理软件CloudCompare的底层核心算法库开发的。后来官方把它从主工程里拆了出来,单独作为一个库来维护和发布。这个库做的事情非常纯粹:点云数据结构定义、八叉树构建与近邻搜索、法线估计、点云配准(ICP、Point-to-Plane等)、距离计算(Cloud-to-Cloud、Cloud-to-Mesh)、Delaunay三角化、泊松重建的前置步骤、各种滤波算法,等等。

换句话说,凡是你在点云处理里能用到的那些底层算法,这个库里基本都有实现。它不依赖任何GUI框架,纯粹就是算法集合,所以可以被各种上层应用引用——CloudCompare本身用它,很多做SLAM、三维重建、工业检测的C++工程也在用它。

用生活化的方式比喻,CCCoreLib就像是一个“点云算法工具箱”,里面每一件工具都已经打磨好了,你只需要把它搬进自己的工程里,按需调用就行,不需要自己再从头去造轮子。这也是为什么很多做点云算法开发的人看到这套源码+lib+dll的编译产物,会特别兴奋——省去了自己编译的整个流程。

1.2 为什么是VS2019编译产物,并且要适配QtCreator

这里有一个非常容易踩坑的细节,很多新手搞不明白:同一个库,用不同的编译器编译出来的二进制文件,在另一个编译器环境下可能是没法用的。

VS2019对应的是MSVC编译器(Microsoft Visual C++),它的ABI(应用程序二进制接口)和MinGW(GCC在Windows上的移植版)是不兼容的。而Qt Creator这个IDE本身支持多种编译器套件(Kit),既可以用MinGW,也可以用MSVC。

所以标题里特别强调“vs2019编译器”,背后的意思实际上是:这套lib和dll是用MSVC 2019编译的,你必须在QtCreator里选择MSVC 2019或兼容的Kit来使用,不能选MinGW套件,否则链接阶段就会因为符号不匹配而报出一堆莫名其妙的错误。

对于很多Windows下拿Qt做上位机、做点云可视化工具的人来说,Qt Creator配合MSVC套件是非常主流的组合。MSVC编译出的程序在Windows上运行性能好,而且和系统API的兼容性也更强。再加上VS2019是目前很多老项目还在用的稳定版本,所以这套编译产物对目标用户来说是刚好能对上号的。

2. 拿到手的源码、lib、dll分别该怎么用

很多刚接触Windows C++开发的同学,看到一个库同时有源码、lib、dll三个东西,会有点懵,不知道哪个是干什么用的。这里我用一个能落地到实际开发的说法来解释。

2.1 源码:不仅是参考,更是调试利器

源码目录里放的是CCCoreLib的所有头文件(.h)以及完整的实现源码(.cpp)。头文件是必须要的,因为你的工程在编译时需要包含它们,才能知道类、函数的声明格式。

而完整的.cpp源码,主要价值有两个:一是调试时可以在IDE里直接跳进库函数的内部实现,看到每一步的中间结果,这在你怀疑是库的行为和预期不符时特别有用;二是当你需要理解某个算法细节、甚至要在自己的工程里定制行为时,直接看源码比查文档高效得多。

当然,源码不是用来重新编译的——至少在你有现成lib和dll的情况下不需要重新编译。除非你想修改库本身的行为,比如改某个算法的参数默认值或增加自定义功能,那才需要把源码加入工程重新编译。

2.2 lib:链接期要用的“索引表”

Windows下使用一个库时,lib文件可以分成两种:一种是静态库,包含代码本体;另一种是动态库的导入库(Import Library),并不包含实现代码,只包含符号索引信息。

标题里同时提到lib和dll,典型的场景就是VS2019编译出的动态库(Release或Debug),配套生成一个导入库(.lib)和动态库(.dll)。编译你的Qt工程时,链接器是靠着lib里的索引信息,知道CCCoreLib里有哪些函数、函数参数格式是什么;真正调用到这些函数时,程序运行期间再去加载dll文件,拿到实际执行代码。

这个过程可以类比成点外卖:lib是菜单,告诉你这家店有什么菜、菜名怎么写(函数签名);dll是后厨,真正把菜做出来的地方;而你的程序就是顾客,先看菜单点菜(编译链接),然后菜从后厨端出来(运行时加载dll执行)。

2.3 dll:运行期真正干活的“执行体”

dll是动态链接库,程序运行时必须能找到它,否则会直接报“程序无法启动,因为计算机中丢失CCCoreLib.dll”之类的错误。

这里要特别强调一个管理习惯:dll不是放在工程文件夹里就万事大吉的,必须让程序在运行时能够定位到它。方法有三种:一是把dll放到和生成的.exe可执行文件同一个目录下;二是把dll所在目录加到系统PATH环境变量里;三是用代码在启动时动态指定加载路径。最简单、最推荐的做法就是第一种——直接把dll拷贝到exe输出目录。

3. QtCreator工程中接入CCCoreLib的完整配置

如果你的工程要从零开始接入这套编译产物,整个配置流程其实并不长,但每步都有讲究。

3.1 第一步:确认你的QtKit用的是MSVC还是MinGW

这一步是生死线。打开QtCreator,进入“工具→选项→Kits”界面,查看当前工程所选的Kit名称和编译器类型。如果显示的是“MSVC2019 64bit”这种,那就没问题;如果是“MinGW 8.1.0 64bit”这种,就说明套件不对。

MSVC和MinGW的ABI完全不兼容,MSVC编译出来的.lib/.dll在MinGW环境里无法使用,链接阶段会报“undefined reference to xxx”或者直接提示文件格式不识别。所以如果你只有这套VS2019编译的产物,就别用MinGW套件了,去安装一个MSVC套件才是正确方向。

在Windows上安装MSVC套件最典型的做法是安装Visual Studio Build Tools或Visual Studio全量版,然后在QtCreator的Kits设置里手动或自动添加检测到的MSVC编译器。新版的QtCreator安装器本身就支持在安装时勾选MSVC套件,安装完会自动识别。

3.2 第二步:在pro文件里配置include和lib路径

假设你的目录结构是这样:

D:/thirdparty/CCCoreLib/ ├─ include/ // 头文件目录 ├─ lib/ │ ├─ CoreLib.lib // Release导入库 │ └─ CoreLibd.lib // Debug导入库 └─ bin/ ├─ CCCoreLib.dll └─ CCCoreLibd.dll

在Qt工程的.pro文件里,需要加上这样的配置:

INCLUDEPATH += D:/thirdparty/CCCoreLib/include

LIBS += -LD:/thirdparty/CCCoreLib/lib

这里有一个细节需要注意:链接哪个lib,要区分Debug和Release版本。如果库作者按惯例在Debug版本的库名后加了字母d(比如CoreLibd.lib),那么你的.pro文件最好写成下面这种,让不同构建模式自动链接不同的lib:

CONFIG(debug, debug|release) {

LIBS += -lCoreLibd

} else {

LIBS += -lCoreLib

}

这么写的好处是,切Debug和Release时不需要手动改.pro文件,不容易犯“Debug工程链接了Release库”的低级错误。

有些库的导入库名和dll名不完全一样,比如lib文件可能叫CCCoreLib.lib,dll叫CCCoreLib.dll。这个无所谓,只要lib里的符号索引指向的dll名称和实际dll文件名一致就行。但最好自己检查一遍:可以用Dependency Walker或者直接看dll的导出表,确认导入库是在引用哪个dll文件名。

3.3 第三步:运行时dll部署

编辑完.pro文件后,重新qmake并构建工程。构建完成后,最重要的一步是:把dll拷贝到exe输出目录。

如果用的是QtCreator默认的构建目录,生成的exe一般在这个位置:

build-你的工程名-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug/debug/你的工程名.exe

对应的dll需要拷贝到这里的debug目录。如果是Release构建,就拷贝到release目录。

注意:MSVC编译的调试版本dll通常依赖“通用C运行时”调试库(ucrtbased.dll等),而这些调试版运行库不是所有机器都默认安装的。调试模式下如果提示缺少这类dll,可以用Visual Studio Installer安装“VC++调试运行时”相关组件。Release模式的dll一般只要装了最新的Microsoft Visual C++ Redistributable就能正常运行。

这里有个更稳妥的办法:用QtCreator构建时添加一个自定义构建步骤,每次构建完成后自动复制dll到输出目录,省去手动拷贝的麻烦。在“项目→构建步骤→添加自定义处理步骤”里,命令写:

cmd /c copy /Y D:/thirdparty/CCCoreLib/bin/CCCoreLib.dll %{buildDir}/debug/

这样每次构建都自动同步,不会忘记拷贝。

4. 实操验证:写一个最小点云程序测试配置

配置好了环境,不写一段代码跑通一遍,总感觉心里没底。下面这个最小Demo是基于CCCoreLib的最典型用法之一——构建点云并做最近邻查询。

4.1 一个基于CCCoreLib的最小点云demo

在main.cpp里写入如下代码:

#include <CCCoreLib/CCLocalModel.h> #include <CCCoreLib/PointCloud.h> #include <CCCoreLib/Neighbourhood.h> #include <cstdio> int main() { // 创建一个点云对象 CCLib::PointCloud cloud; if (!cloud.reserve(100)) { printf("点云内存预留失败\n"); return -1; } // 随机填入100个点 srand(42); for (unsigned i = 0; i < 100; ++i) { CCCoreLib::CCVector3 p( static_cast<float>(rand()) / RAND_MAX * 10.0f, static_cast<float>(rand()) / RAND_MAX * 10.0f, static_cast<float>(rand()) / RAND_MAX * 10.0f); cloud.addPoint(p); } // 构建八叉树 CCCoreLib::DgmOctree octree(&cloud); if (octree.build() != CCCoreLib::DgmOctree::SUCCESS) { printf("八叉树构建失败\n"); return -1; } // 查询第0号点的最近邻 CCCoreLib::DgmOctree::NearestNeighboursSphericalSearchStruct nss; nss.queryPoint = cloud.getPoint(0); nss.level = octree.findBestLevelForAGivenPopulationPerCell(10); nss.minNumberOfNeighbors = 1; if (octree.getNearestNeighbours(nss) > 0) { printf("最近邻距离: %f\n", std::sqrt(nss.neighbours[0].squareDist)); } return 0; }

这段代码做的事情是:创建一个包含100个随机点的点云,构建八叉树加速结构,然后查询第0个点的最近邻并输出距离。编译运行成功后,如果控制台打印出一个合理的距离值,就说明CCCoreLib的头文件包含、lib链接、dll加载全部正常。

这里我用了CCCoreLib::CCVector3这样带命名空间的写法,但需要注意不同版本的头文件结构可能略有差异。有些老版本是直接CCLib命名空间,新版本已经统一改为CCCoreLib。如果你include的时候找不到头文件,先自查一下头文件路径是否在include目录里。

4.2 编译运行可能出现的首个错误

最容易遇到的编译错误是“无法打开包含文件CCCoreLib/PointCloud.h:No such file or directory”。这个错误出现,基本是INCLUDEPATH路径没配对,或者头文件目录层级和include语句不一致。

建议先看一眼实际解压后的目录结构:include下面是不是还有一层嵌套目录。比如实际路径是D:/thirdparty/CCCoreLib/CCCoreLib/PointCloud.h,那INCLUDEPATH应该加D:/thirdparty/CCCoreLib而不是D:/thirdparty/CCCoreLib/include。头文件写的是#include <CCCoreLib/PointCloud.h>,编译器会在所有INCLUDEPATH路径下寻找子目录CCCoreLib,所以要保证能从某个INCLUDEPATH出发,按相对路径找到这个头文件。

5. 踩坑实录:VS2019 + QtCreator + CCCoreLib常见问题排查

这套组合我实际用过很长一段时间,以下问题基本是每次帮别人排查时最容易撞上的,我直接按“症状、原因、解法”的格式整理出来,方便你对照参考。

5.1 报错“无法打开文件CCCoreLib.lib”

这个报错说明链接器找不到lib文件。优先检查.pro里的-L指定的路径是否存在、lib文件名是否准确。Windows下的lib文件名不区分大小写,但路径区分,要确认盘符和目录层级完全无误。

另一个容易忽略的问题:如果lib文件名里带版本号(比如CCCoreLib-1.2.lib),而.pro里写的是-lCCCoreLib,链接器会在lib目录里查找CCCoreLib.liblibCCCoreLib.lib,找不到就会报错。最好直接写绝对路径的lib文件,最稳妥:

LIBS += D:/thirdparty/CCCoreLib/lib/CCCoreLib.lib

5.2 报错“程序无法启动,找不到CCCoreLib.dll”

这个错误我见过太多次了,基本都是dll没拷贝到exe所在目录。特别是用了QtCreator的多个构建套件或构建目录时,exe可能有好几个输出位置,debug和release各一个,容易拷错地方。

一个非常实用的技巧是:用Process Explorer或ListDLLs工具查看程序实际加载的dll路径,确认加载的是不是你拷贝的那个版本。有时候系统PATH里还有个老版本的dll,程序优先加载了它,导致行为异常但表面看“找到了dll”。

5.3 Debug和Release混用导致的崩溃

这是最隐蔽的坑。如果你在Debug模式下链接了Release版lib,编译可能通过,但运行时会崩溃,或者数据结果异常。原因和MSVC的运行时库机制有关:Debug模式链接的是Debug版CRT(malloc、memcpy等函数的调试版本),Release库链的是Release版CRT,两者在堆管理上不兼容,跨越边界分配和释放内存时直接出问题。

解决办法就是在.pro里区分Debug和Release链接不同的lib版本,同时确保dll也对应正确版本。如果库只提供了Release版本,那你的应用就必须用Release模式编译,不能图方便在Debug下跑。

5.4 中文路径和编码问题

VS2019的MSVC编译器对源文件编码敏感。如果你的.cpp文件里有中文注释,而文件编码不是UTF-8 with BOM,编译器可能会报奇怪的错误。最新版的VS2019已经默认支持UTF-8 without BOM,但如果是从老工程带过来的文件,还是建议统一转成UTF-8 with BOM。

另外,工程路径和库所在路径尽量不要有中文和空格。MSVC的导入库机制在空格路径下偶尔会出问题,这类问题排查起来最浪费时间,不如一开始就规避掉。

5.5 一个更隐蔽的坑:CCCoreLib版本和CloudCompare版本的对应

市面上流传的CCCoreLib编译产物有时来自不同版本的源码。老版本的CCCoreLib头文件里声明的是CCLib命名空间,新版本才改成CCCoreLib。如果你的工程里有其他代码是从CloudCompare老版本项目里抄来的,就可能导致命名空间不匹配,编译出一堆“XX has not been declared”错误。

解决思路是检查你手里的头文件里实际用的是哪个命名空间,然后修改自己的调用代码去适配。具体操作是:打开include目录下的PointCloud.h,直接看文件顶部namespace后面的名字是什么,以实际为准,不要凭记忆和网上教程去猜。

6. 个人经验和一点扩展建议

这套VS2019编译的CCCoreLib,配QtCreator的MSVC套件,是我个人在Windows下做点云处理验证时最顺手的一套组合。QtCreator的代码编辑体验、调试体验比VS轻量,而CCCoreLib又能把点云底层的脏活累活全部包揽掉,专注业务层开发非常舒服。

最后再分享一个实用技巧:如果你需要在多个工程里反复用这套编译产物,建议在自己电脑上做一个统一的第三方库管理目录,比如D:/thirdparty/,把CCCoreLib、PCL、OpenCV等按固定结构放好。每个工程只要三处改动——INCLUDEPATH、LIBS、dll拷贝——就搞定集成。这个习惯养成之后,新建工程的成本会大幅下降。

如果后面打算商用或者需要自己改算法逻辑,建议把源码也纳入版本管理,直接把CCCoreLib源码加入你的解决方案里一起编译,这样调试时可以直接跳进库源码。但在那之前,先用这套现成的lib+dll把业务跑通,是最省时的路径。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询