简介:这份资源是面向C++开发者的paho.mqtt.cpp库VS2019编译成品,适合需要在Windows平台快速接入MQTT协议、又不想从零折腾编译环境的工程师与学习者。压缩包共550个文件,约64.21MB,涵盖h头文件、cpp源码、vcxproj工程、lib与dll库文件,以及pdb调试符号、obj中间产物、cmake配置脚本和log日志等,源码与编译产物齐备,可直接引用或二次开发。已有2978人学习下载,说明其在MQTT C++实践场景中具备一定参考价值。拿到后可直接获得可用的静态库与动态库,省去CMake配置与依赖编译的繁琐过程,同时保留完整工程结构,便于对照源码理解客户端接口、消息收发与连接管理机制,也方便在VS2019中调试排错、按需裁剪模块,快速集成到自有项目中。
1. 从一次链接报错说起:VS2019 下 paho.mqtt.cpp 到底该怎么装
第一次在 VS2019 里用 paho.mqtt.cpp,我卡在链接阶段整整一个下午。CMake 配置过了,头文件也找到了,编译到一半却报LNK2019 无法解析的外部符号,翻来覆去查路径、查库名,最后发现是 Debug 和 Release 两套库混用了——paho.mqtt.cpp 依赖 paho.mqtt.c,而 c 库的 Debug 版和 Release 版文件名只差一个后缀,CMake 找错了目录,链接器自然找不到符号。这个坑在 MQTT C++ 开发里太常见了,尤其是从零搭环境的人,往往以为装完库就完事,结果卡在编译链接上。
paho.mqtt.cpp 是 Eclipse Paho 项目下的 C++ 客户端库,封装了底层的 paho.mqtt.c,提供同步和异步两种 API,适合在 Windows 桌面程序、工业上位机、嵌入式网关这类场景里做 MQTT 通信。VS2019 是很多团队还在用的工具链,MSVC 的 ABI 和运行时库配置跟 Linux 下差别不小,装不好就是一堆 unresolved external。这篇笔记按「环境准备 → 编译 c 库 → 编译 cpp 库 → 工程配置 → 验证排错」的顺序走一遍,目标是你照着能编出可用的库文件,并且知道哪一步容易翻车。
2. 环境准备:VS2019、CMake 和依赖库的版本选择
2.1 工具链版本对照
paho.mqtt.cpp 对工具链有最低要求,版本选错会在 CMake 配置阶段直接报错。下面是我在几台机器上验证过的组合,按这个来基本不会出玄学问题。
| 组件 | 推荐版本 | 最低要求 | 说明 |
|---|---|---|---|
| Visual Studio | 2019 16.11 | 2019 16.0 | 需勾选「使用 C++ 的桌面开发」 |
| CMake | 3.20 以上 | 3.13 | 低于 3.13 不支持某些 target 语法 |
| paho.mqtt.c | 1.3.13 | 1.3.9 | cpp 库的底层依赖,必须先编 |
| paho.mqtt.cpp | 1.3.2 | 1.2.0 | 本文主角 |
| OpenSSL | 1.1.1 系列 | 1.1.1 | 需要 TLS 时才装,不用可跳过 |
VS2019 安装时注意勾选 MSVC v142 生成工具和 Windows 10 SDK,这两个是编译 c 库和 cpp 库的基础。如果只装了 VS 没装 CMake,去 CMake 官网下 Windows 安装包,安装时勾选「Add CMake to the system PATH」,不然后面命令行调不到。
2.2 源码获取与目录规划
paho.mqtt.c 和 paho.mqtt.cpp 是两个独立仓库,cpp 库编译时需要通过PAHO_MQTT_C_PATH或 CMake 变量找到 c 库的头文件和库文件。我一般把两个仓库放在同一个父目录下,结构清晰,CMake 找起来也方便:
# 目录结构建议 D:\mqtt_build\ ├── paho.mqtt.c-1.3.13\ # c 库源码 ├── paho.mqtt.cpp-1.3.2\ # cpp 库源码 ├── install\ # 统一安装前缀 │ ├── include\ │ ├── lib\ │ └── bin\ └── build\ # 各库的构建目录 ├── c_build\ └── cpp_build\源码从 Eclipse Paho 官方仓库获取,下载对应版本的源码包解压即可。不要用太新的 master 分支,版本号对不上的时候 API 可能有变动,编译报错不好排查。我一般锁定 release tag,比如v1.3.13和v1.3.2。
2.3 环境变量与命令行准备
编译过程主要靠 CMake 命令行完成,VS2019 自带的「x64 Native Tools Command Prompt for VS 2019」是最省事的入口,它已经配好了 MSVC 的编译环境变量。从开始菜单找到这个命令行工具,以管理员身份运行,后续所有命令都在这个窗口里执行。
# 验证环境是否就绪 cmake --version # 应输出 cmake version 3.20.x 或更高 cl # 应输出 Microsoft (R) C/C++ Optimizing Compiler Version 19.29.x如果cl命令找不到,说明没在 VS 原生工具命令行里操作,或者 VS 安装时漏了 C++ 工作负载。这种情况重新打开正确的命令行入口即可,不需要重装 VS。
提示:不要用普通的 cmd 或 PowerShell 直接跑 CMake,MSVC 的环境变量没加载,CMake 会找不到编译器,报「No CMAKE_CXX_COMPILER could be found」。
3. 编译 paho.mqtt.c:底层依赖先跑通
3.1 CMake 配置参数详解
c 库是 cpp 库的基础,必须先编译安装。进入 c 库源码目录,用 CMake 生成 VS2019 工程。关键参数有三个:CMAKE_INSTALL_PREFIX指定安装路径,PAHO_BUILD_STATIC控制是否编静态库,PAHO_WITH_SSL控制是否启用 TLS。
cd D:\mqtt_build\paho.mqtt.c-1.3.13 mkdir ..\build\c_build cd ..\build\c_build cmake ..\..\paho.mqtt.c-1.3.13 ^ -G "Visual Studio 16 2019" ^ -A x64 ^ -DCMAKE_INSTALL_PREFIX=D:\mqtt_build\install ^ -DPAHO_BUILD_STATIC=TRUE ^ -DPAHO_BUILD_SHARED=TRUE ^ -DPAHO_WITH_SSL=FALSE ^ -DPAHO_BUILD_SAMPLES=FALSE参数逐个说明:-G "Visual Studio 16 2019"指定生成 VS2019 工程文件,-A x64指定 64 位平台,这两个必须匹配你的目标架构。CMAKE_INSTALL_PREFIX是安装前缀,后面 cpp 库编译时要指向同一个路径。PAHO_BUILD_STATIC和PAHO_BUILD_SHARED我一般两个都开,静态库方便集成到单个 exe,动态库方便多程序共享。PAHO_WITH_SSL=FALSE表示不启用 TLS,如果你的 MQTT broker 要求加密连接,改成 TRUE 并确保 OpenSSL 已安装且 CMake 能找到。PAHO_BUILD_SAMPLES=FALSE跳过示例程序,减少编译时间。
3.2 编译与安装
CMake 配置成功后,用--build参数编译,再用--install安装到指定前缀。注意--config参数要分别编 Debug 和 Release,两个版本都要,后面 cpp 库链接时按需选用。
# 编译 Release 版本 cmake --build . --config Release --target install # 编译 Debug 版本 cmake --build . --config Debug --target install编译完成后检查安装目录,应该能看到头文件和库文件:
dir D:\mqtt_build\install\include # 应包含 MQTTClient.h、MQTTClientPersistence.h 等 dir D:\mqtt_build\install\lib # 应包含 paho-mqtt3c.lib、paho-mqtt3cs.lib 等 # Debug 版通常带 d 后缀,如 paho-mqtt3cd.lib如果install目录下只有 Release 没有 Debug,说明第二次编译时 CMake 缓存没刷新,删掉c_build目录重新配置即可。这个坑我踩过,Debug 库缺失会导致后面 cpp 库在 Debug 模式下链接失败。
3.3 常见编译错误处理
c 库编译本身不算复杂,但有两个错误比较典型。一个是error C2065: 'snprintf': undeclared identifier,这是老版本 MSVC 对 C99 支持不完整导致的,paho.mqtt.c 1.3.9 以后已经修复,如果遇到就升级版本。另一个是LNK1181: cannot open input file 'ws2_32.lib',说明 Windows SDK 没装全,去 VS Installer 里补上「Windows 10 SDK」组件。
注意:编译 c 库时如果开了
PAHO_WITH_SSL=TRUE但 OpenSSL 路径没配,CMake 会在配置阶段报Could NOT find OpenSSL。这种情况要么关掉 SSL,要么用-DOPENSSL_ROOT_DIR指定 OpenSSL 安装路径。
4. 编译 paho.mqtt.cpp:链接 c 库的关键配置
4.1 指定 c 库路径的两种方式
cpp 库编译时最核心的问题是让 CMake 找到刚才编好的 c 库。有两种方式:一种是通过PAHO_MQTT_C_PATH环境变量,另一种是直接传-DPAHO_MQTT_C_INCLUDE_DIR和-DPAHO_MQTT_C_LIBRARIES。我一般用后者,参数显式,出问题好排查。
cd D:\mqtt_build\paho.mqtt.cpp-1.3.2 mkdir ..\build\cpp_build cd ..\build\cpp_build cmake ..\..\paho.mqtt.cpp-1.3.2 ^ -G "Visual Studio 16 2019" ^ -A x64 ^ -DCMAKE_INSTALL_PREFIX=D:\mqtt_build\install ^ -DPAHO_MQTT_C_INCLUDE_DIR=D:\mqtt_build\install\include ^ -DPAHO_MQTT_C_LIBRARIES=D:\mqtt_build\install\lib\paho-mqtt3c.lib ^ -DPAHO_BUILD_STATIC=TRUE ^ -DPAHO_BUILD_SHARED=TRUE ^ -DPAHO_BUILD_SAMPLES=FALSE ^ -DPAHO_BUILD_TESTS=FALSEPAHO_MQTT_C_INCLUDE_DIR指向 c 库头文件目录,PAHO_MQTT_C_LIBRARIES指向 c 库的导入库文件。注意这里写的是 Release 版的paho-mqtt3c.lib,Debug 版会在编译时自动匹配对应的paho-mqtt3cd.lib,前提是 c 库两个版本都装了。PAHO_BUILD_TESTS=FALSE跳过测试代码,测试代码依赖 GoogleTest,不关掉会额外下载依赖,拖慢编译。
4.2 编译 Debug 与 Release 双版本
和 c 库一样,cpp 库也要分别编两个版本。这里有个细节:--target install会把头文件和库文件复制到CMAKE_INSTALL_PREFIX,但 Debug 和 Release 的库文件名不同,不会互相覆盖。
# Release cmake --build . --config Release --target install # Debug cmake --build . --config Debug --target install编译完成后检查安装目录:
dir D:\mqtt_build\install\lib # 应包含 paho-mqttpp3.lib(Release) # 以及 paho-mqttpp3d.lib(Debug)如果只看到 Release 版没有 Debug 版,检查 CMake 配置时PAHO_MQTT_C_LIBRARIES是否指向了正确的路径,以及 c 库的 Debug 版是否真的安装了。我遇到过 c 库 Debug 版没装,cpp 库 Debug 编译时链接器找不到paho-mqtt3cd.lib,报LNK1104。
4.3 静态库与动态库的取舍
PAHO_BUILD_STATIC和PAHO_BUILD_SHARED两个开关控制生成哪种库。静态库(.lib)在链接时直接嵌入 exe,部署时不需要额外带 DLL,适合单文件分发;动态库(.dll + .lib)多程序共享,更新库不用重新编译 exe,适合多模块项目。
我一般两个都编,实际项目里按需选用。如果选动态库,部署时要把paho-mqtt3c.dll和paho-mqttpp3.dll复制到 exe 同目录,否则运行时报「找不到 xxx.dll」。这个坑在第一次部署时几乎必踩,调试时一切正常,拷到别的机器就起不来。
提示:静态库链接时如果报
LNK2005: 符号重复定义,检查是否同时链接了静态版和动态版的 c 库。两个版本的符号会冲突,只保留一个。
5. 避坑排查:VS2019 集成时的五个高频问题
5.1 LNK2019 无法解析的外部符号
现象:编译自己的 MQTT 客户端代码时,链接阶段报大量LNK2019,符号名类似mqtt::async_client::connect。
原因:最常见的是库文件没链接全,或者 Debug/Release 版本混用。paho.mqtt.cpp 依赖 paho.mqtt.c,两个库都要在项目里配置。另一个原因是平台不匹配,比如库是 x64 但项目是 Win32。
解决:在 VS 项目属性里检查「链接器 → 输入 → 附加依赖项」,确保paho-mqttpp3.lib和paho-mqtt3c.lib都在。Debug 配置下应使用带d后缀的版本。再检查「链接器 → 常规 → 附加库目录」是否指向D:\mqtt_build\install\lib,以及「C/C++ → 常规 → 附加包含目录」是否指向D:\mqtt_build\install\include。
5.2 运行时找不到 DLL
现象:编译通过,但运行 exe 时弹窗报「找不到 paho-mqttpp3.dll」或「找不到 paho-mqtt3c.dll」。
原因:动态库版本编译时,exe 运行时需要加载对应的 DLL,而 DLL 不在系统搜索路径里。
解决:把D:\mqtt_build\install\bin下的所有 DLL 复制到 exe 同目录。或者把该目录加入系统 PATH 环境变量。我一般直接在项目里配「生成后事件」,自动拷贝 DLL:
xcopy /Y /I "D:\mqtt_build\install\bin\*.dll" "$(OutDir)"这行命令放在「项目属性 → 生成事件 → 生成后事件 → 命令行」里,每次编译后自动把 DLL 拷到输出目录,省得手动复制。
5.3 CMake 配置阶段找不到 c 库
现象:cpp 库 CMake 配置时报Could NOT find Paho MQTT C,或者PAHO_MQTT_C_INCLUDE_DIR被忽略。
原因:路径写错,或者路径里有空格没加引号。Windows 路径用反斜杠时,CMake 可能解析异常。
解决:路径统一用正斜杠/或双反斜杠\\,避免单反斜杠转义问题。如果路径含空格,用引号包起来。检查PAHO_MQTT_C_INCLUDE_DIR下确实有MQTTClient.h,PAHO_MQTT_C_LIBRARIES指向的文件确实存在。
5.4 Debug 模式下断言失败
现象:Debug 版程序运行到 MQTT 连接时触发断言,Release 版正常。
原因:Debug 版库和 Release 版库的运行时库配置不一致,比如一个用/MDd一个用/MD,导致堆内存管理冲突。
解决:确保项目属性和库的编译配置一致。VS 项目默认 Debug 用/MDd,Release 用/MD,paho 库编译时 CMake 也会按配置生成对应的运行时库设置。如果手动改过项目的运行时库选项,改回默认值。
5.5 编译速度慢或卡死
现象:cmake --build执行很久没反应,或者卡在某个文件上。
原因:开了PAHO_BUILD_TESTS=TRUE时,CMake 会下载 GoogleTest,网络不好就卡住。或者开了PAHO_BUILD_SAMPLES=TRUE,编译大量示例代码。
解决:配置时加上-DPAHO_BUILD_TESTS=FALSE -DPAHO_BUILD_SAMPLES=FALSE,只编库本身。如果已经卡住,Ctrl+C 中断,删掉cpp_build目录重新配置。
6. 装完怎么验证:一个最小 MQTT 客户端的编译与运行
库编好了,怎么确认它真的能用?我一般写一个最小的 MQTT 客户端,连本地 broker 发一条消息,跑通就算验证完成。这个习惯是从一次「库编出来了但 API 用不了」的翻车经历之后养成的——那次头文件和库版本不匹配,编译通过但运行崩溃,查了半天才发现是版本错位。
6.1 最小验证代码
在 VS2019 里新建一个空的控制台项目,配置好包含目录和库目录,然后写下面这段代码。它连接本地 MQTT broker,订阅一个主题,发一条消息,收到后退出。
// mqtt_verify.cpp #include <mqtt/async_client.h> #include <iostream> #include <string> #include <thread> #include <chrono> const std::string SERVER_ADDRESS("tcp://localhost:1883"); const std::string CLIENT_ID("verify_client"); const std::string TOPIC("test/verify"); int main() { mqtt::async_client client(SERVER_ADDRESS, CLIENT_ID); // 设置连接选项,自动重连 auto connOpts = mqtt::connect_options_builder() .clean_session(true) .automatic_reconnect(true) .finalize(); try { // 连接 broker client.connect(connOpts)->wait(); std::cout << "connected" << std::endl; // 订阅主题 client.subscribe(TOPIC, 1)->wait(); // 发布一条消息 auto msg = mqtt::make_message(TOPIC, "hello paho"); client.publish(msg)->wait(); // 等消息回环 std::this_thread::sleep_for(std::chrono::seconds(2)); // 断开连接 client.disconnect()->wait(); std::cout << "disconnected" << std::endl; } catch (const mqtt::exception& exc) { std::cerr << "error: " << exc.what() << std::endl; return 1; } return 0; }这段代码用了异步客户端的同步等待方式,->wait()把异步操作转成阻塞调用,适合验证场景。connect_options_builder是 1.3.x 版本的推荐写法,老版本用connect_options直接构造。automatic_reconnect(true)让客户端在断线后自动重连,生产环境一般会开。
6.2 编译配置检查清单
在 VS 项目属性里逐项核对:
| 配置项 | 路径 | 说明 |
|---|---|---|
| C/C++ → 常规 → 附加包含目录 | D:\mqtt_build\install\include | 头文件搜索路径 |
| 链接器 → 常规 → 附加库目录 | D:\mqtt_build\install\lib | 库文件搜索路径 |
| 链接器 → 输入 → 附加依赖项 | paho-mqttpp3.lib;paho-mqtt3c.lib | Release 配置 |
| 链接器 → 输入 → 附加依赖项 | paho-mqttpp3d.lib;paho-mqtt3cd.lib | Debug 配置 |
| C/C++ → 代码生成 → 运行时库 | /MD(Release)//MDd(Debug) | 与库保持一致 |
Debug 和 Release 配置要分别设置,VS 默认只改当前活动配置,切到另一个配置时记得再检查一遍。这个细节坑过很多人,Release 编过了切 Debug 就报错,原因就是附加依赖项没改。
6.3 运行验证与结果判读
本地需要一个 MQTT broker,用 Mosquitto 最省事,装完默认监听 1883 端口。启动 broker 后运行编译出的 exe,正常输出应该是:
connected disconnected如果卡在connected之后没输出,检查 broker 是否在运行,以及防火墙是否拦了 1883 端口。如果报connection refused,说明 broker 没启动或者地址端口不对。如果报error: MQTT error [-1],多半是库版本和头文件不匹配,重新检查安装目录里的头文件版本号是否和库文件对应。
我一般还会用mosquitto_sub订阅同一个主题,确认消息真的发出去了:
mosquitto_sub -h localhost -t test/verify -v # 应输出:test/verify hello paho两边对上了,说明库编译、链接、运行整条链路都通了。从那以后我每次编完 paho.mqtt.cpp,都会先跑这个最小验证,确认 API 能调、消息能收发,再往正式项目里集成。希望帮到你。
本文还有配套的精品资源,点击获取