简介:CCCoreLib是CloudCompare的核心算法库,面向三维点云处理开发者与研究者。这份资源提供VS2019编译器生成的完整源码、lib静态库与dll动态库,可直接导入QtCreator工程使用,免去自行编译与依赖配置的繁琐过程。包体包含102个文件,其中63个头文件与34个cpp源文件覆盖点云读取、几何分析、配准、分割等核心模块,另附1个lib、1个dll和1个hpp,整体仅567KB,轻量且结构清晰。已有492人学习下载。借助该资源可快速调用ccLoadCloud、ccCompareClouds等API,在Qt环境中实现点云处理、算法修改与功能扩展,适合希望深入CloudCompare开发或学习其核心实现的开发者。 说实话,点云处理这个圈子绕不开 CloudCompare,而 CCCoreLib 就是它背后那个真正干活的算法内核。遇到过的情况大概是这样的:自己写 Qt 桌面程序要集成点云滤波、法线估计、ICP 配准这些功能,不想从零造轮子,于是拉了一份 CCCoreLib 源码,准备在 Windows 上编出 lib/dll 给工程用。结果一堆人卡在“源码有了,VS2019 也装了,QtCreator 就是死活链接不上,各种 LNK 报错”。这篇文章就把我从拿到源码到在 QtCreator 里跑通全流程捋一遍,涉及到 VS2019 编译器选型、CMake 生成工程、lib/dll 的生成和调用,以及几个典型的坑,给后面做点云应用开发的人一个可以直接抄的作业。
1. 项目背景与整体思路
1.1 CCCoreLib 是什么,为什么要在 QtCreator 里用
CCCoreLib 是 CloudCompare 的算法核心库,里面封装了大量点云和网格处理的基础算法,比如八叉树建树、最近邻搜索、法线估计、ICP 配准、泊松重建、栅格降采样、连通分量分割这些。说得直白一点,CloudCompare 软件本身只是一个壳子,真正的计算逻辑基本都抽到了这个库里。
对做工业测量、三维扫描后处理、机器人感知相关项目的人来说,直接在自有 Qt 工程里复用这套算法是非常诱人的一件事:一是算法经过 CloudCompare 多年验证,稳定性有保障;二是不用自己研究怎么把几十个源文件组织成工程,省掉很多基础设施时间。但问题也跟着来了——CCCoreLib 官方在 Windows 下的推荐编译方式是 MSVC(也就是 VS2019),而很多桌面开发者的日常 IDE 是 QtCreator,两者要配合,就必须经过一层“先编译库、再接入工程”的处理。
在动手之前需要明确一件事:QtCreator 只是个 IDE,真正编译代码的是编译器。QtCreator 下常见的编译器有 MinGW GCC 和 Microsoft Visual C++(MSVC 两种。VC的lib/dll跟MinGW的a/dll不是一套ABI,直接混用几乎必炸。所以我们整个方案的起点就是:用 VS2019 编译源码,产出 dll/lib,再让 QtCreator 切换到 MSVC 工具链去消费这两个文件。
1.2 编译方案选型:为什么选 VS2019 + CMake
CCCoreLib 的仓库是标准的 CMake 工程,没有强行绑定 Qt,纯 C++ 算法库,依赖相对可控。选 VS2019 作为编译器有几点考虑:一是官方 Windows 构建脚本和 CI 用的就是 MSVC,出问题能少踩一半坑;二是 QtCreator 从 4.x 开始对 MSVC 套件支持得已经很成熟,完全可以在 QtCreator 里写代码、用 MSVC 编译,逻辑上并不矛盾。
另一个方案是直接用 QtCreator 打开源码里的 CMakeLists.txt,让 QtCreator 自动配置生成工程,这确实也能做,但有几个麻烦点:QtCreator 默认会把 CMake 生成的构建目录结构弄得比较“个性”,而且如果装的是新版本 CMake,QtCreator 内部的 CMake 版本也可能跟 VS2019 的生成器存在兼容问题。我的建议是更传统但更可控的两段式:先用 CMake 命令行生成 VS2019 解决方案,在 VS2019 里点两下编译生成 dll/lib;再去 QtCreator 里通过 .pro 文件把库链进自己的应用工程。这样每一步产物是清楚的,出了问题也容易定位。
2. 环境准备与源码获取
2.1 开发环境清单与版本匹配
这个环节看着基础,但不少人恰恰是这里没到位导致后面连环报错。整套环境的版本组合我用的是经过验证的:
| 组件 | 版本建议 | 说明 |
|---|---|---|
| 操作系统 | Windows 10/11 64位 | 32位环境建议直接放弃,点云数据量上去后内存根本不够 |
| VS2019 | Community 16.11 及以上 | 务必安装“使用 C++ 的桌面开发”工作负载 |
| CMake | 3.20 以上 | VS2019 对应的 MSVC 生成器需要 CMake 3.14+ 才支持完整特性 |
| Qt | 5.15 或 6.2+ | QtCreator 建议安装“MSVC 2019 64bit”构建套件 |
| Git | 任意较新版本 | 拉取源码用 |
有两点我要特别强调。第一,VS2019 安装时一定要把 Windows 10 SDK 勾上,否则 QtCreator 里的 MSVC 工具链会因为缺少 SDK 而无法识别。我见过有人 VS 装完只选了 C++ 编译核心,结果 QtCreator 里能看到编译器却无法构建,排查了半天才发现是 SDK 缺失。第二,如果机器上同时装了 VS2019 和 VS2022,QtCreator 会自动检测到多个 MSVC 版本,选择套件时务必看清楚,Kit 名称里会直接标识 “MSVC2019 64bit” 还是 “MSVC2022 64bit”,选错的话链接阶段符号版本不一致,报错会非常诡异。
2.2 获取源码与目录结构梳理
源码直接从 GitHub 仓库拉取,参照 CloudCompare 官方仓库中的 CCCoreLib 子项目。整体目录结构大概是这样的:
CCCoreLib/ ├── include/ │ ├── CCCoreLib.h │ ├── CCCoreLibConfig.h │ ├── DgmOctree.h │ ├── PointCloudTpl.h │ ├── ... ├── src/ │ ├── DgmOctree.cpp │ ├── PointCloudTpl.cpp │ ├── ... ├── plugins/ ├── CMakeLists.txt ├── LICENSE这个库的头文件组织比较规整,公开接口基本都集中在 include 目录,源码在 src 目录。它依赖的第三方库很少,核心部分基本不需要额外下载依赖,只有用到某些扩展算法时才会涉及到 Eigen 之类的外部库。所以拉完源码直接跑 CMake 就可以,不需要像 OpenCV 那样先装一堆依赖。
多说一句,如果用 git clone 要注意分支。master 分支跟随上游开发,API 变化会比较频繁。如果用稳定版本,建议 checkout release 标签,比如 v2.0.0 之类的版本号,这样后续链接阶段不会因为接口签名变化而反复改代码。我一开始直接拉 master,编译倒是过了,但后来发现某个类的方法在两周后的提交里被重命名了,Qt 工程里调用处全部编译失败,后来老老实实切到 release 分支才消停。
3. 用 VS2019 编译 CCCoreLib 生成 lib 和 dll
3.1 CMake 配置生成 VS 工程
打开“x64 Native Tools Command Prompt for VS2019”,或者用普通 CMD 但确保 CMake 在 PATH 里。在源码根目录执行:
cmake -S . -B build -G "Visual Studio 16 2019" -A x64这条命令指定了生成器为 VS2019,架构为 x64。如果不指定 -A x64,CMake 默认可能会生成 Win32 工程,后面链接 x64 的 dll 时会因为位数不一致直接报错。所以位数这件事情,从 CMake 生成阶段就要死死定住,不要寄希望于后面再切换。
生成成功后,build 目录下会看到CCCoreLib.sln解决方案文件。双击打开,在解决方案管理器中找到CCCoreLib项目,右键“生成”。第一次编译会比较慢,主要是要编译的源文件数量和模板实例化都不少,大概在几十个 cpp 的规模。编译结束后,在build/Release/或build/Debug/目录下能看到产物。
关于 Debug 与 Release 的选择,我建议同时编两个版本。Debug 版本的 DLL 和 Release 版本不能混用,否则运行时会随机崩溃或者出现莫名其妙的“内存访问冲突”。不少人的 Qt 程序自己编译用的是 Debug 模式,结果链接的 CCCoreLib 是 Release 库,表面看没报错,一运行就挂,花了很多时间查业务逻辑,最后发现是库配置混了。
3.2 动态库与静态库的选择
这里涉及一个关键选项:CCCoreLib 在 CMake 中默认编译类型由BUILD_SHARED_LIBS控制。默认情况下可能是静态库,可以通过 CMake 配置显式指定:
cmake -S . -B build_dll -G "Visual Studio 16 2019" -A x64 -DBUILD_SHARED_LIBS=ON两种方式各有适用的场景,我建议按照下面的标准来选:
| 方式 | 产物 | 优点 | 缺点 |
|---|---|---|---|
| 静态库 | CCCoreLib.lib(体积较大) | 部署简单,exe 一个文件带走,无 DLL 缺失问题 | 编译时间长,exe 体积膨胀 |
| 动态库 | CCCoreLib.dll + CCCoreLib.lib(导入库) | 更新库时只需替换 DLL,多个程序可共享 | 部署时必须带上 DLL,还要处理运行路径 |
我的做法是:如果只是自己项目内部使用,优先静态库,省去一大堆 DLL 路径问题;如果打算把库作为插件体系的一部分,或者多个可执行模块都要复用同一个算法库,那就上动态库。下面我按动态库方式继续讲,因为工作中遇到的大多数问题场景都是 DLL 方式。
3.3 输出产物与头文件配套
生成动态库后,实际需要保留的文件如下:
CCCoreLib.dll # 运行时要加载的动态库 CCCoreLib.lib # 链接时使用的导入库 include/ # 全部头文件,调用方编译需要有个细节很多人会忽略:include/CCCoreLibConfig.h这个文件是整个库编译导出的关键配置头。CCCoreLib 使用CC_CORE_LIB_API这类宏来控制导入导出,而这个宏定义在CCCoreLibConfig.h中。如果你把这个文件漏了,或者用了源码里错误的版本,链接阶段会有一大堆“无法解析的外部符号”报错。所以拷贝头文件时,整个 include 目录原样搬走,千万别手动筛。
编译完成后,在 build 目录下的 CMakeCache.txt 里还埋着很多有用的路径信息,比如依赖的三方库路径、安装路径等。不过对我们这种只取库文件的使用方式,不需要执行cmake --install,手动拷贝即可。
4. 在 QtCreator 工程中接入
4.1 用 .pro 组织包含路径与链接参数
假设你的 Qt 工程是一个标准 qmake 管理的 Widgets 程序,那么接入工作主要写在.pro文件里。我的.pro核心片段如下:
# 编译使用 MSVC2019 64bit 套件的前提下 CONFIG += c++17 INCLUDEPATH += $$PWD/../CCCoreLib/include CONFIG(debug, debug|release) { LIBS += -L$$PWD/../CCCoreLib/build/Debug -lCCCoreLib } else { LIBS += -L$$PWD/../CCCoreLib/build/Release -lCCCoreLib } # 如果你不是用相对路径,也可以用绝对路径 # LIBS += -LC:/dev/libs/CCCoreLib -lCCCoreLib # Windows 下建议打开这个,否则某些平台相关的 min/max 宏会干扰算法头文件 DEFINES += NOMINMAX这里的-lCCCoreLib会在指定目录下查找CCCoreLib.lib(MSVC 工具链)或libCCCoreLib.a(MinGW 工具链)。如果链接阶段找不到库,就去检查-L指定的目录和-l的库名是否精确匹配。文件名无规则变化是 Link 报 LNK1104 的常见原因。
重点解释一下NOMINMAX这个宏。Windows 的windows.h里定义了min和max宏,而 CCCoreLib 的模板代码里大量使用了std::numeric_limits<T>::max()这种标准写法。如果不禁用 Windows 宏,编译器会把代码里的max直接替换成宏,导致一大堆语法错误。这个问题在 MSVC 工具链下基本是必现的,Qt 的某些模块会在全局引入 Windows 头,所以提前在.pro里加 DEFINES 是最稳妥的。
4.2 构建套件必须选择 MSVC
QtCreator 安装后,默认会带一个 MinGW 套件,很多新手直接用这个套件去编译,然后链 VS2019 生成的 lib,结果一堆 LNK2001、LNK2019 无法解析的外部符号。原因很简单:MinGW 的 C++ 符号修饰规则(name mangling)跟 MSVC 不一样,两边编出来的 obj 文件根本不是一套 ABI。
正确操作是在 QtCreator 菜单“工具 -> 选项 -> Kits”下添加或选择 MSVC2019 64bit 套件。前提是安装 VS2019 时勾选了 C++ 工作负载,QtCreator 才能自动检测到 MSVC 工具链。套件配置要点:
| 配置项 | 设置 |
|---|---|
| 编译器 | Microsoft Visual C++ Compiler 16.x (x86/amd64) |
| 调试器 | 使用 CDB 或 windows 下的 gdb(建议 CDB) |
| Qt 版本 | 选择 Qt 5.15.x 或 Qt 6.x 的 MSVC 版本 |
| CMake 工具 | 系统安装的 CMake |
这里要特别提醒:如果你想彻底避开调试器那一堆麻烦,最简单的方式是把编译器选正确,然后构建、运行都用这个套件。如果你发现构建套件列表里根本没有 MSVC,八成是 VS2019 安装时没有安装“使用 C++ 的桌面开发”工作负载,回去重新修改安装即可,不用重装 VS。
4.3 运行时部署 DLL 与依赖检查
把程序编译通过只是第一步,运行时 DLL 找不到是第二大高频问题。QtCreator 直接按“运行”按钮时,它会设置一个特定的 PATH,但往往不包含你的 CCCoreLib.dll 所在目录。处理方式有几种,从简单到规范排列:
- 把
CCCoreLib.dll复制到生成的 exe 同目录下,简单直接。 - 在 QtCreator 的“运行环境”里新增 PATH 项,把 DLL 所在目录加进去。
- 在
.pro中使用QMAKE_POST_LINK,在每次构建完成后自动拷贝 DLL,适合频繁迭代的场景。
# 每次构建后自动拷贝 DLL 到目标目录 win32 { CONFIG(debug, debug|release) { QMAKE_POST_LINK += $$quote(cmd /c copy /Y $$PWD/../CCCoreLib/build/Debug/CCCoreLib.dll $$OUT_PWD/debug/) } else { QMAKE_POST_LINK += $$quote(cmd /c copy /Y $$PWD/../CCCoreLib/build/Release/CCCoreLib.dll $$OUT_PWD/release/) } }把这两行加进去之后,每次 F5 运行都不会再出现“找不到 CCCoreLib.dll”的弹窗。此外,可以用 Dependencies 这类工具检查 DLL 的依赖树,确保 CCCoreLib.dll 本身没有缺少它自己的运行时组件(比如 VCRUNTIME140.dll)。正常情况下 VS2019 编译的 DLL 会依赖 VC++ 运行库,目标机器如果没有安装 VC++ Redistributable,程序同样起不来,这是部署到其他电脑时重点关注的一项。
5. 常见问题与排查技巧实录
5.1 高频报错速查表
我整理了自己实际踩过或者说身边朋友问过最多的几类问题,按出现频率排序:
| 报错现象 | 根本原因 | 解决办法 |
|---|---|---|
| LNK1104 无法打开文件 CCCoreLib.lib | 库路径不对,或库文件名大小写、后缀不一致 | 检查 .pro 的 -L 路径;确认生成的 lib 是 Release 还是 Debug |
| LNK2001/LNK2019 无法解析的外部符号 | MinGW 与 MSVC 混用,或头文件宏定义不一致 | 统一使用 MSVC2019 构建套件;确认CCCoreLibConfig.h中的导入导出宏正常生效 |
| 运行时提示找不到 CCCoreLib.dll | DLL 不在 exe 目录或 PATH 中 | 将 DLL 拷贝到 exe 目录,或用 QMAKE_POST_LINK 自动部署 |
编译时报 C4996,locale相关告警且无法定位 | MSVC 对 locale 的安全警告 | 在 .pro 增加DEFINES += _CRT_SECURE_NO_WARNINGS屏蔽 |
| Qt 程序一运行就崩溃,且崩溃点在随机位置 | Debug 库和 Release 库混用 | 整条工具链统一 Debug 或 Release,禁止混搭 |
| 程序体积异常巨大,且链接奇慢 | 可能存在大量模板实例化 | 可以考虑改用动态库;若无效则关闭 /GL 等全局优化重新链接 |
其中最坑的其实是第一个 LNK1104。因为 QtCreator 构建时默认把构建目录放在 build-工程名-套件名-配置 这种子目录里,很多人的.pro文件写的是相对路径,写到$$PWD/../lib/结果发现相对于build目录不同层级,导致找不到,建议优先用绝对路径或者通过变量传递路径。
5.2 几个“断根式”的避坑心得
第一,永远保持架构一致。x64 的 Qt 工程只能链接 x64 的 CCCoreLib.lib。很多人 VS 编译时没注意平台,生成了 Win32 的库,Qt 工程又是 x64,链接阶段直接报错,这种问题往往要查很久。生成 VS2019 工程时用-A x64就能从源头杜绝。
第二,小心源码中的中文注释。VS2019 默认对源码文件按系统 ANSI 代码页解析,如果源码文件是 UTF-8 无 BOM 格式且包含中文注释,MSVC 可能报 C4819 警告,严重时直接编译失败。碰到时在源码根目录的 CMakeLists 里全局加编译选项,或者在 VS2019 中给项目增加/utf-8编译参数。QtCreator 侧也可以在.pro里加QMAKE_CXXFLAGS += /utf-8。这个坑在第三方源码仓库里尤其常见,因为它们的主力维护者大概率不在中文 Windows 环境下开发,文件格式不一定兼容本地编码设置。
第三,一定把集成测试写好再推进业务。库接进来后,先写一个最小可执行样例做好 sanity check,比如建一个简单的点云容器插入几千个点,然后算一次八叉树半径搜索,确认结果在合理范围。这一步看着简单,但能一次性暴露架构、编码、链接、运行期 PATH 的所有问题,省下的排查时间远大于写这几行测试的时间。
我个人每次接手这种第三方库集成时的习惯是:先读目标库的 CMakeLists 前 80 行,确认默认构建选项,再决定用静态库还是动态库,然后才动手跑 CMake。这个习惯帮我避开过好几次因为默认关闭了共享库导出宏导致的链接异常。CCCoreLib 的文档不算多,但官方 GitHub 的 Issues 区非常活跃,遇到疑难问题先去那边搜,很多时候你会发现自己遇到的问题别人三个月前就踩过了。
本文还有配套的精品资源,点击获取