尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

VS2019编译paho.mqtt.cpp库完整指南:从依赖到链接

发布时间:2026/9/29 16:02:50

资讯中心
01
ARTICLE

VS2019编译paho.mqtt.cpp库完整指南:从依赖到链接

VS2019编译paho.mqtt.cpp库完整指南:从依赖到链接
简介在VS2019环境下可直接使用的paho.mqtt.cpp预编译库包面向需要快速接入MQTT协议的C开发者能省去手动编译第三方库的环境配置时间。压缩包内包含完整工程源码、头文件、编译生成的dll动态库与lib静态库并附有CMake构建文件、Visual Studio解决方案sln及多个vcxproj工程配置便于在现有项目中直接引用也可对照源码和构建配置深入理解库的生成过程。资源共550个文件以tlog构建日志、cpp源文件、h头文件、vcxproj工程文件为主另有obj中间文件、pdb调试符号、exe示例程序及cmake配置等压缩包整体约64.21MB。配套的详细编译教程与包内文件相互印证能帮助使用者快速定位编译过程中的关键环节并规避常见错误。目前已有2976人学习下载适合熟悉C但不愿在MQTT库编译上消耗时间的Windows平台开发者。1. VS2019编译paho.mqtt.cpp库自己动手反而比下载快我原来图省事直接用网上下好的 paho.mqtt.cpp 预编译包结果换台机器就翻车要么缺 DLL要么 TLS 握手直接崩连日志都看不出所以然。折腾两天后我回到源码用 VS2019 从头把 paho.mqtt.cpp 库编了一遍所有链接问题一次性清空。这个标题说的事情很具体paho.mqtt.cpp 是 Eclipse Paho 给 C 写的 MQTT 客户端库在 Windows 上编译它不像普通 C 库那样一条命令收工它先要编底层的 paho.mqtt.c再编上层的 C 封装中间还涉及 OpenSSL 和 CMake 版本。如果你在 Windows 上用 C 写 MQTT 客户端、要连 TLS 端口或者不想被预编译包绑定特定编译器这条路径值得你完整走一遍。2. 编译前先理清依赖paho.mqtt.cpp 是一套两层结构2.1 库的真身底层 C 库加 C 封装paho.mqtt.cpp 实际上不是一个单纯的上层代码仓库它是对 paho.mqtt.c 的 C 封装。底层 C 库负责真正的 MQTT 协议解析、会话状态、网络收发C 库提供mqtt::client、mqtt::async_client、mqtt::message这类面向对象的接口。也就是说你用 VS2019 编译 paho.mqtt.cpp 时第一步往往不是在编 C 代码而是在给底层的 C 库生成可用的 DLL 和导入库。CMake 的组织方式也印证了这点paho.mqtt.cpp 的 CMakeLists.txt 里通过find_package(paho-mqtt-c)去查找底层 C 库找不到就直接报错。所以手工编译的顺序必须是先 C 后 C或通过 vcpkg 让依赖自动串起来。还有一个可选依赖是 OpenSSL只有在你的编译配置里打开 PAHO_WITH_SSL 开关时才会用到。通常的做法是编译时先把 SSL 开关关掉跑通非 TLS 链路再按需打开重编这样排查问题会简单很多。2.2 两条构建路径vcpkg 一键装还是手动 CMake在 Windows 上构建这个库有两条主流路径。一条是 vcpkg一条是手动 CMake。vcpkg 适合你想快速拿到可用库、不在乎产物目录结构的情况手动 CMake 适合你要控制架构、运行时库、SSL 开关、安装路径的场景。# vcpkg 路径一条命令把 C 库、C 库、OpenSSL 全部编好 C:\dev\vcpkg\vcpkg.exe install paho-mqtt-cpp[ssl]:x64-windows这条命令里[ssl]是 feature 开关表示要带 TLS 支持x64-windows指定目标 triplet也就是 x64 架构、动态 CRT 链接。vcpkg 会把 paho.mqtt.c、OpenSSL 一并作为依赖编完再产出 paho-mqtt-cpp 的 DLL 和导入库。这条路的优势是版本匹配由 vcpkg 保证不用自己调 CMake 参数劣势是产物分散在 vcpkg 的 installed 目录里而且 CtrlC 中断后有时会留下半成品库后续清理有点麻烦。我一般会先检查 vcpkg 版本和已安装的 triplet 列表确认工程里其他库也用同一套 triplet避免混用 Debug/Release 或 x86/x64 的库。如果你的项目有严格安全要求不允许引入 vcpkg 这类包管理器或者 CMake 需要指向统一的第三方库目录那手动编译就是更可靠的路径。vcpkg 适合验证想法手动 CMake 适合工程化落地。2.3 工具链核对VS2019 对应的 CMake 生成器使用 VS2019 编译 paho.mqtt.cpp 库CMake 生成器必须明确写成Visual Studio 16 2019。如果 CMake 检测不到正确生成器最常见的原因是只装了 VS2022 或只装了 Build Tools。另一个容易忽略的点是命令行工具的环境问题。CMake 在 VS2019 下默认生成的是解决方案文件之后由 MSBuild 编译所以你要保证 VS2019 的 C 工作负载已安装包括“适用于 Windows 的 C CMake 工具”这个组件。:: 检查 cmake 是否可用并确认版本号 cmake --version :: 查看当前系统支持的 VS 生成器 cmake --helpcmake --help输出的列表里应当能看到 Visual Studio 16 2019。如果看不到说明 CMake 版本过低或 VS2019 未注册到系统。另一个常见场景是 Qt 工程很多人会在 VS2019 里配合 Qt 5.15 使用Qt 的工具链名是 msvc2019_64它要求外部第三方库也必须用同一个编译器工具链编paho.mqtt.cpp 也不例外。架构混乱会导致链接器给你一堆莫名其妙的 unresolved external symbol十有八九不是代码问题而是库与工程的架构或工具集不一致。3. 用 CMake 在 VS2019 下编译 paho.mqtt.cpp完整命令与参数3.1 第一步先编译底层 paho.mqtt.c源码准备好后我把两个仓库放在同一级目录下比如C:\workspace\paho.mqtt.c和C:\workspace\paho.mqtt.cpp产物统一安装到C:\libs\paho这样后面 C 库查找 C 库时路径非常干净。以下是我在一台纯净 VS2019 环境里实际跑通的命令序列。cd C:\workspace\paho.mqtt.c cmake -G Visual Studio 16 2019 -A x64 \ -DCMAKE_INSTALL_PREFIXC:/libs/paho \ -DPAHO_WITH_SSLTRUE \ -DPAHO_BUILD_SHAREDTRUE \ -DPAHO_BUILD_STATICFALSE \ -DPAHO_ENABLE_TESTINGFALSE \ -S . -B build cmake --build build --config Release cmake --install build --config Release参数里最关键的是-DPAHO_WITH_SSLTRUE它决定底层 C 库是否带 TLS 支持如果你后面要连 8883 端口必须在这里打开。-DPAHO_BUILD_SHAREDTRUE生成动态库-DPAHO_BUILD_STATICFALSE关闭静态库这样能减少产物种类避免把自己绕晕。-DCMAKE_INSTALL_PREFIX指定安装根目录后续 C 库配置时用同一个路径。-S . -B build是 CMake 的新式参数写法-S指定源码目录-B指定构建目录比旧式cmake .清晰很多。构建目录里的 CMakeCache.txt 记录了所有配置项如果之后想切换架构或 SSL 开关最好把 build 目录整体删掉重新配置不要原地改否则 CMake 会沿用一堆旧缓存经常导致链接时用了错误配置的库。3.2 第二步编译 paho.mqtt.cpp 并对齐配置底层 C 库安装完成后开始编 C 封装层。这里最大的坑是 SSL 开关与 C 库不一致比如 C 库编了 SSLC 层没开CMake 配置阶段直接报找不到 OpenSSL 或 paho-mqtt-c 版本不匹配。cd C:\workspace\paho.mqtt.cpp cmake -G Visual Studio 16 2019 -A x64 \ -DCMAKE_PREFIX_PATHC:/libs/paho \ -DCMAKE_INSTALL_PREFIXC:/libs/paho \ -DPAHO_WITH_SSLTRUE \ -DPAHO_BUILD_SHAREDTRUE \ -DPAHO_BUILD_STATICFALSE \ -DPAHO_ENABLE_TESTINGFALSE \ -S . -B build cmake --build build --config Release cmake --install build --config Release与第一步相比多了一个-DCMAKE_PREFIX_PATHC:/libs/pahoCMake 会在这个路径下执行find_package(paho-mqtt-c)。paho.mqtt.cpp 的 CMake 脚本会检查底层的版本、配置和 SSL 选项如果对你的paho-mqtt-c不满意会明确要求你重建底层库。-DPAHO_WITH_SSLTRUE必须与 C 库一致这里不一致的后果是链接阶段报一堆 OpenSSL 的 unresolved external。编译完成后C:\libs\paho目录结构大致如下。include 下同时出现 C 库和 C 库的头文件lib 下出现两类导入库。注意 Debug 和 Release 的产物要分开编我通常用build_release和build_debug两个构建目录避免混用。目录或文件说明C:\libs\paho\include\mqtt\client.hC 库核心头文件C:\libs\paho\include\MQTTClient.hC 库头文件C 层会间接引用C:\libs\paho\lib\paho-mqtt3a.libC 库 Release 动态版的导入库C:\libs\paho\lib\paho-mqtt-cpp.libC 库导入库C:\libs\paho\bin\paho-mqtt3a.dllC 库运行期 DLLC:\libs\paho\bin\paho-mqtt-cpp.dllC 库运行期 DLL如果在bin下找不到 DLL或者名字带d后缀多半是构建配置选错。我用 Release 配置构建时产物里不会带调试标记Debug 配置才会输出带调试信息的库注意别把两个混在一个目录里。3.3 静态库与动态库的选择一个容易后悔的决策我在第一版工程里图省事选了动态库后来要部署到客户现场时对方要求单目录分发不想带一堆 DLL只好重编静态版本。静态版本需要把-DPAHO_BUILD_SHAREDFALSE和-DPAHO_BUILD_STATICTRUE同时设好而且链接时还要额外添加系统库依赖。cmake -G Visual Studio 16 2019 -A x64 \ -DCMAKE_PREFIX_PATHC:/libs/paho \ -DCMAKE_INSTALL_PREFIXC:/libs/paho_static \ -DPAHO_WITH_SSLTRUE \ -DPAHO_BUILD_SHAREDFALSE \ -DPAHO_BUILD_STATICTRUE \ -S . -B build_static cmake --build build_static --config Release cmake --install build_static --config Release静态库产品在 Windows 下需要注意如果你的工程运行时库设置是/MT而库编的时候是/MD链接会报 LNK2038 这类运行时库冲突其次是静态链接 C 库时头文件里可能有对应的宏定义需要打开paho.mqtt.c 的头文件会检查类似PAHO_MQTT_C_STATIC这样的宏来决定导入导出方式不定义的话会看到奇怪的链接错误。我一般建议新手先用动态库跑通确认业务代码没问题再根据部署需求切静态。4. 把编译好的库集成进 VS2019 工程属性表、链接项与运行路径4.1 用属性表把 include 与 lib 目录固定下来库编好了接下来是集成到自己的 VS2019 工程。我习惯做一个 paho.props 属性表而不是每次新建工程都手动填 VS 的目录配置。属性表可以复用换工程时右键添加现有属性表即可。把下面内容保存为paho.props放在仓库的 build 目录里。?xml version1.0 encodingutf-8? Project ToolsVersion4.0 xmlnshttp://schemas.microsoft.com/developer/msbuild/2003 ImportGroup LabelPropertySheets / PropertyGroup LabelUserMacros PahoRootC:\libs\paho/PahoRoot /PropertyGroup ItemDefinitionGroup ClCompile AdditionalIncludeDirectories$(PahoRoot)\include;%(AdditionalIncludeDirectories)/AdditionalIncludeDirectories PreprocessorDefinitionsPAHO_MQTT_C_STATIC;_WIN32_WINNT0x0601;%(PreprocessorDefinitions)/PreprocessorDefinitions /ClCompile Link AdditionalLibraryDirectories$(PahoRoot)\lib;%(AdditionalLibraryDirectories)/AdditionalLibraryDirectories AdditionalDependenciespaho-mqtt3a.lib;paho-mqtt-cpp.lib;ws2_32.lib;crypt32.lib;%(AdditionalDependencies)/AdditionalDependencies /Link /ItemDefinitionGroup /Project属性表里有几个关键点。AdditionalIncludeDirectories指向安装目录的 include这是 C 和 C 两套头文件的共用目录。AdditionalLibraryDirectories指向 lib 目录。AdditionalDependencies里paho-mqtt3a.lib是 C 库的导入库paho-mqtt-cpp.lib是 C 库的导入库ws2_32.lib和crypt32.lib是 Windows 下网络与加密相关的系统库静态链接场景几乎必加。PAHO_MQTT_C_STATIC这个预处理器定义是我编静态库时确认的宏它让 C 库头文件用静态库的导入导出规则。用动态库时这个宏不定义因为 DLL 的导入声明由导入库自动处理。为了不让属性表变成黑匣子我建议你在工程里先只配 include 和库目录跑一个最小程序确认链接通过后再逐步加其他依赖项。4.2 附加依赖项与链接顺序为什么 paho-mqtt3a.lib 排在前面Windows 链接器处理.lib时没有特别严格的顺序要求但实际工程里把底层库排在前面、上层库排在后面能减少一种奇怪现象当上层库和底层库同时导出一组符号时链接器会按顺序匹配第一条可满足的符号。paho.mqtt.cpp 的代码直接调用 C 库的MQTTClient.h接口理论上顺序影响不大但按底层在前、上层在后形成依赖链排查问题时能少走弯路。:: 检查导入库中导出的符号确认库内容与头文件匹配 dumpbin /headers C:\libs\paho\lib\paho-mqtt-cpp.lib | findstr DLL name这是一个很实用的验证手段。dumpbin /headers可以查看导入库对应的 DLL 名称和架构信息。如果依赖项配置了 paho-mqtt-cpp.lib但实际编译出的 DLL 叫别的名字这里就能提前发现。注意 dumpbin 需要从 VS2019 的开发者命令行启动普通 cmd 里找不到这个命令。4.3 运行期 DLL 分发放到 exe 目录还是改 PATH链接成功后进入运行期最常见的问题是双击 exe 报“找不到 paho-mqtt3a.dll”。Windows 加载 DLL 的顺序是 exe 所在目录、系统目录、PATH 环境变量。我不建议把 DLL 拷到 system32也不建议改全局 PATH最干净的做法是把运行期需要的 DLL 放在 exe 同目录并随程序一起分发。:: 在 VS2019 生成事件里自动拷贝 DLL copy /Y C:\libs\paho\bin\paho-mqtt3a.dll $(OutDir) copy /Y C:\libs\paho\bin\paho-mqtt-cpp.dll $(OutDir)在工程的“生成事件 → 后期生成事件命令行”里加上这两行每次编译后自动同步 DLL。这样项目复制到别的机器时整个目录带走就能跑也不用为环境变量这类玄学问题浪费半天。如果你同时用了 OpenSSL别漏了libcrypto-3-x64.dll和libssl-3-x64.dll它们在 vcpkg 的 installed 目录下或者在你手动指定的 OpenSSL bin 目录下。这些 DLL 漏掉任何一个运行时的报错都差不多但排查起来却要花不少时间。5. paho.mqtt.cpp 编译与链接的常见坑现象、原因、解决5.1 运行时报“找不到 paho-mqtt3a.dll”现象编译和链接全部通过运行 exe 时立即弹出无法启动程序、找不到 paho-mqtt3a.dll。原因C 库的 DLL 没有和 exe 放在一起系统也扫描不到。很多人在集成 paho.mqtt.cpp 时只关注 C 库的 DLL忘了底层 C 库也有独立的 DLLpaho-mqtt3a.dll 是底层库的运行产物。解决把安装目录 bin 下的 paho-mqtt3a.dll、paho-mqtt-cpp.dll以及依赖的 OpenSSL DLL 全部拷到 exe 输出目录。检查方法是打开 exe 所在目录确认 DLL 文件真实存在如果程序是 64 位的确认你拷贝的是 x64 版本不要把 x86 的 DLL 放进 x64 程序目录。5.2 LNK2038 与运行时库不匹配现象链接时报LNK2038 mismatch detected for RuntimeLibrary: value MT_StaticRelease doesnt match value MD_DynamicRelease。原因库编译时用的是动态 CRT/MD你的工程却设置成了静态 CRT/MT两个配置强制链接在一起必然冲突。这个问题的根源通常是你把预编译包或不同机器编出来的库混进了工程。解决统一运行时库设置。最简单的方法是把工程属性里的“运行库”改成和多线程 DLL 一致或者重编一份与你工程匹配的库。如果你必须用 /MT那 paho.mqtt.c、paho.mqtt.cpp、OpenSSL、工程四者的编译选项都得是静态 CRT任何一个不统一都会报错。5.3 编译出来的库只有 C 接口没有 mqtt::client现象头文件里找不到mqtt/async_client.h或者代码里用mqtt::client时报找不到声明你只看到了MQTTClient.h这类 C 风格接口。原因你编的是 paho.mqtt.c不是 paho.mqtt.cpp。两个仓库的源码目录里都有 CMakeLists.txt但只有 paho.mqtt.cpp 的构建才会生成 C 层头文件和 paho-mqtt-cpp.lib。如果命令在C:\workspace\paho.mqtt.c下执行不管编多少次产物都是 C 库。解决确认你cmake -S . -B build的当前目录在 paho.mqtt.cpp 源码根目录且 include 路径里能看到mqtt子目录。5.4 连接 8883 端口失败SSL 根本没编进去现象程序能连 1883但连 8883 时报 TLS 初始化失败或者握手直接超时。原因编译时-DPAHO_WITH_SSLTRUE没有打开或者底层 C 库开了 SSL 但 C 层没开。这个坑隐蔽的地方在于 CMake 配置阶段不会强制报错SSL 支持被当作可选项处理编出来的库在运行时才暴露问题。解决回到第 3 章的编译命令两个库都显式设-DPAHO_WITH_SSLTRUE并且确认 CMake 能找到 OpenSSL。找不到的话在 CMake 配置时加上-DOPENSSL_ROOT_DIRC:/libs/openssl指定 OpenSSL 的安装路径然后再重新编一次。5.5 CMake 一直找到旧版本或错误架构的 C 库现象CMake 配置 paho.mqtt.cpp 时提示找到的 paho-mqtt-c 版本不符或者链接时符号解析失败。原因find_package(paho-mqtt-c)沿用了系统路径或其他缓存里的旧配置。比如你之前用 vcpkg 装过一次 C 库现在手动编了新版CMake 仍然优先找到旧版。解决删除 paho.mqtt.cpp 的 build 目录和 CMakeCache.txt重新配置同时用-DCMAKE_PREFIX_PATH显式指定你手动安装的路径。不要在已经配置过的 build 目录里反复改参数CMake 的缓存机制在这种情况下不给后悔药删掉重来最快。6. 验证库可用性的最后一招跑通最小发布/订阅链路库配置完成后我每次都会写一个最小的发布/订阅程序验证链路而不是直接上线业务代码。这个程序的目的很简单验证库能连上 broker、能发布消息、能收到自己的消息整个链路通就不用在集成问题上浪费精力。#include mqtt/async_client.h #include iostream #include chrono int main() { const std::string server tcp://broker.emqx.io:1883; const std::string clientId paho_vs2019_check; const std::string topic paho/vs2019/check; constexpr int qos 1; mqtt::async_client cli(server, clientId); mqtt::connect_options opts; opts.set_keep_alive_interval(std::chrono::seconds(20)); opts.set_clean_session(true); cli.connect(opts)-wait(); auto msg mqtt::make_message(topic, hello_vs2019); msg-set_qos(qos); cli.publish(msg)-wait(); cli.subscribe(topic, qos)-wait(); std::cout publish and subscribe ok, waiting 3s for callback... std::endl; std::this_thread::sleep_for(std::chrono::seconds(3)); cli.disconnect()-wait(); return 0; }这段代码用mqtt::async_client异步客户端但写法是同步等待适合验证。connect_opts里的keep_alive_interval设 20 秒clean_session为 true 表示连接断开不保留会话状态。publish后手动subscribe同一个 topic因为 QoS 1 下 broker 会转发给自己订阅端能收到就说明库的收发链路正常。跑这个程序时如果卡在 connect 或 publish 的 wait 上说明网络或 broker 配置有问题如果正常打印并退出说明库本身没有大问题。这个最小验证程序我保留在仓库里每换一台机器或升级一次库版本第一件事就是跑它。paho.mqtt.cpp 这个库本身封装得不错但 Windows 下编译集成的坑都在库之外DLL 分发、运行时库匹配、SSL 开关一致性、CMake 缓存每一个都能浪费半天。把这些验证脚本和属性表沉淀成固定的工程模板后续开发会顺畅很多。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。