资讯动态

QT5.10.1与minGW5.10.1下编译MQTT模块并连接阿里云物联网平台

发布时间:2026/10/16 7:23:47 来源:尧图企业网站定制
简介该资源面向在 Qt 环境下开发物联网通信的开发者尤其是需要将 MQTT 协议接入阿里云物联网平台的初学者与进阶者。它基于 Qt 5.10.1 与 minGW 5.10.1 编译环境调用第三方 qmqtt 库实现了 Connect、Publish、Subscribe、Unsubscribe 等核心功能可直接作为 Qt 移植 MQTT 与云端对接的参考工程。压缩包共 28 个文件约 1.91MB包含 20 个头文件、2 个 cpp 源文件、1 个 ui 界面文件、1 个 pro 工程文件以及 2 个 dll 与 2 个 a 静态库文件覆盖 qmqtt 客户端、网络接口、消息路由、SSL 与 WebSocket 等模块结构完整便于二次开发。目前已有 2115 人学习下载。读者可从中获取 Qt 集成 MQTT 的工程组织方式、阿里云物联网平台连接与消息收发流程以及库文件与头文件的配套使用思路适合作为课程设计、毕业设计或物联网项目原型的起步模板。1. 从一台新装的 Windows 开发机说起QT5.10.1 配 MQTT 到底卡在哪上周帮同事配一台新笔记本装完 QT5.10.1 和 minGW5.10.1 之后他以为打开 Qt Creator 就能直接连阿里云物联网平台结果在QT mqtt那一行就卡住了——Qt 5.10.1 官方安装包里根本没有 MQTT 模块。这不是个例我见过太多人在这套组合上翻车有人去 GitHub 拉了源码但不知道用 minGW 怎么编有人编出来了但运行时提示缺Qt5Mqtt.dll还有人把 32 位和 64 位的库混着用编译通过但一跑就崩。这套环境之所以常见是因为 QT5.10.1 搭配 minGW5.10.1 是很多嵌入式上位机和工控项目的标配而 MQTT 又是对接阿里云物联网平台最省事的协议。装不好后面所有联调都无从谈起。这篇笔记就是把我自己反复装过几遍的流程拆开从版本选择到编译配置再到验证跑通一步步写清楚。2. 环境准备QT5.10.1 与 minGW5.10.1 的版本对齐2.1 为什么必须锁定 QT5.10.1 minGW5.10.1 这个组合Qt 的版本和编译器绑定关系比很多人想象的要严格。QT5.10.1 官方提供的 Windows 安装包里minGW 版本就是 5.10.1这是 Qt 官方编译好的配套工具链。如果你用 minGW 7.x 或 8.x 去编 Qt 的 MQTT 模块大概率会遇到undefined reference to __gxx_personality_v0这类链接错误原因是 ABI 不兼容。我一般会先确认三件事Qt Creator 的「关于」里显示的 Qt 版本是不是 5.10.1编译器路径是不是指向Qt5.10.1\Tools\mingw530_32\bin或对应 64 位目录以及qmake -v输出的版本号。这三者必须一致否则后面编译 MQTT 源码时会出现各种玄学问题。2.2 安装 QT5.10.1 时勾选哪些组件运行 Qt 官方安装程序时在组件选择页面不要全勾。我通常只选这几项Qt 5.10.1 下的MinGW 5.10.1 32-bit如果你的目标板是 64 位系统就选 64-bitQt Creator 4.x安装包里自带的版本即可Sources这一项建议勾上后面编译 MQTT 模块时可能需要用到 Qt 的源码头文件安装路径不要带空格和中文这是血泪经验。我见过有人装在C:\Program Files\Qt下结果 qmake 生成的 Makefile 里路径带空格make 直接报错。改成C:\Qt\Qt5.10.1这种纯英文无空格路径最稳妥。2.3 验证 minGW 工具链是否可用装完之后别急着开 Qt Creator先打开命令行验证一下工具链# 把 minGW 的 bin 目录加入 PATH或者直接用绝对路径 C:\Qt\Qt5.10.1\Tools\mingw530_32\bin\gcc --version C:\Qt\Qt5.10.1\Tools\mingw530_32\bin\g --version C:\Qt\Qt5.10.1\5.10.1\mingw53_32\bin\qmake -v三条命令分别输出 gcc、g 和 qmake 的版本信息。如果 gcc 报「不是内部或外部命令」说明 PATH 没配好如果 qmake 输出的 Qt 版本不是 5.10.1说明你调用了系统里其他版本的 Qt。这一步看起来简单但我遇到过的编译失败里有三分之一是这里没对齐导致的。3. 编译 MQTT 模块从源码到可用的 Qt5Mqtt 库3.1 获取 Qt MQTT 源码并切换到匹配分支Qt 的 MQTT 模块在官方仓库里是独立维护的不在主安装包里。你需要单独获取源码。打开命令行找一个干净目录git clone https://code.qt.io/qt/qtmqtt.git cd qtmqtt git branch -a列出分支后找到5.10或5.10.1对应的分支并切换过去git checkout 5.10这里有个坑如果你直接 clone 默认分支通常是 dev 或 5.15编译出来的库和 QT5.10.1 的 ABI 不匹配链接时会报一堆找不到符号的错误。所以分支一定要和你的 Qt 版本对应。3.2 用 qmake 生成 Makefile 并编译切换好分支后用 QT5.10.1 自带的 qmake 来生成构建文件# 进入源码目录 cd qtmqtt # 创建一个构建目录保持源码干净 mkdir build cd build # 用 Qt5.10.1 的 qmake 生成 Makefile C:\Qt\Qt5.10.1\5.10.1\mingw53_32\bin\qmake ..\qtmqtt.pro # 用 minGW 的 make 编译 C:\Qt\Qt5.10.1\Tools\mingw530_32\bin\mingw32-make -j4-j4表示用 4 个线程并行编译加快速度。编译过程大概两三分钟如果中途报错最常见的原因是 qmake 版本不对或者源码分支不匹配。编译成功后在build/lib目录下会生成libQt5Mqtt.a、libQt5Mqttd.a调试版以及对应的.dll文件。3.3 安装库文件和头文件到 Qt 目录编译出来的库需要放到 Qt 能识别的位置否则你在项目里写QT mqtt时 qmake 找不到模块。我一般手动拷贝比make install更可控# 拷贝头文件 xcopy /E /I ..\src\mqtt C:\Qt\Qt5.10.1\5.10.1\mingw53_32\include\QtMqtt # 拷贝静态库和动态库 copy build\lib\libQt5Mqtt.a C:\Qt\Qt5.10.1\5.10.1\mingw53_32\lib\ copy build\lib\Qt5Mqtt.dll C:\Qt\Qt5.10.1\5.10.1\mingw53_32\bin\ # 拷贝模块配置文件 copy build\lib\qt_lib_mqtt.pri C:\Qt\Qt5.10.1\5.10.1\mingw53_32\mkspecs\modules\qt_lib_mqtt.pri这个文件很关键它告诉 qmake 在QT mqtt时应该链接哪些库、包含哪些头文件路径。少了它qmake 会报Unknown module(s) in QT: mqtt。3.4 在 .pro 文件中启用 MQTT 模块库装好之后在你的项目.pro文件里加上一行QT mqtt然后执行qmake重新生成 Makefile再mingw32-make。如果编译通过说明 MQTT 模块已经正确集成。我习惯在main.cpp里加一个简单的头文件包含来验证#include QtMqtt/QMqttClient #include QDebug int main(int argc, char *argv[]) { QMqttClient client; client.setHostname(iot-as-mqtt.cn-shanghai.aliyuncs.com); client.setPort(1883); qDebug() MQTT client created, host: client.hostname(); return 0; }这段代码不实际连接只是创建一个客户端对象并打印主机名。如果能编译运行且输出正常说明库和头文件都到位了。4. 对接阿里云物联网平台参数配置与连接验证4.1 阿里云物联网平台的三元组参数怎么填阿里云物联网平台为每个设备分配了三元组ProductKey、DeviceName、DeviceSecret。在 MQTT 连接时你需要用这三个参数构造 ClientID、Username 和 Password。常见做法是用 HMAC-SHA1 对 DeviceSecret 进行签名生成 Password。具体格式如下参数构造规则示例值虚构ClientID{DeviceName}{ProductKey}device01pk_abc123Username{DeviceName}{ProductKey}device01pk_abc123PasswordHMAC-SHA1(DeviceSecret, 拼接字符串)40 位十六进制字符串Broker Address{ProductKey}.iot-as-mqtt.cn-shanghai.aliyuncs.compk_abc123.iot-as-mqtt.cn-shanghai.aliyuncs.comPort1883非加密或 8883TLS1883签名用的拼接字符串格式是clientId{ClientID}deviceName{DeviceName}productKey{ProductKey}timestamp{时间戳}时间戳用毫秒级 Unix 时间。这个签名逻辑在阿里云文档里有详细说明我一般会封装成一个函数避免每次手写。4.2 用 QMqttClient 建立连接的核心代码下面是一个最小可运行的连接示例基于 QT5.10.1 的 MQTT 模块#include QtMqtt/QMqttClient #include QDebug #include QCryptographicHash #include QMessageAuthenticationCode // 生成阿里云 MQTT 密码 QString generatePassword(const QString deviceSecret, const QString clientId, const QString deviceName, const QString productKey) { QString timestamp QString::number(QDateTime::currentMSecsSinceEpoch()); QString content clientId clientId deviceName deviceName productKey productKey timestamp timestamp; QByteArray secretBytes deviceSecret.toUtf8(); QByteArray contentBytes content.toUtf8(); QByteArray sign QMessageAuthenticationCode::hash( contentBytes, secretBytes, QCryptographicHash::Sha1).toHex(); return QString(sign); } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QMqttClient client; QString productKey pk_abc123; // 替换为你的 ProductKey QString deviceName device01; // 替换为你的 DeviceName QString deviceSecret your_secret; // 替换为你的 DeviceSecret QString clientId deviceName productKey; client.setHostname(productKey .iot-as-mqtt.cn-shanghai.aliyuncs.com); client.setPort(1883); client.setClientId(clientId); client.setUsername(clientId); client.setPassword(generatePassword(deviceSecret, clientId, deviceName, productKey)); QObject::connect(client, QMqttClient::connected, []() { qDebug() Connected to Aliyun IoT platform!; // 订阅自定义 Topic client.subscribe( / productKey / deviceName /user/test); }); QObject::connect(client, QMqttClient::messageReceived, [](const QByteArray message, const QMqttTopicName topic) { qDebug() Received: message on topic: topic.name(); }); client.connectToHost(); return app.exec(); }这段代码里generatePassword函数用QMessageAuthenticationCode做 HMAC-SHA1 签名这是 Qt 自带的加密类不需要额外依赖。连接成功后订阅了一个自定义 Topic用于接收平台下发的消息。注意 Topic 的格式必须符合阿里云规范否则会被拒绝。4.3 编译时链接哪些库在.pro文件里除了QT mqtt还需要加上网络模块QT core network mqtt如果用到 TLS 加密连接端口 8883还需要QT network并确保 OpenSSL 库可用。不过对于内网测试1883 端口足够用。编译命令和普通 Qt 项目一样qmake mingw32-make生成的 exe 文件需要和Qt5Mqtt.dll、Qt5Network.dll放在同一目录或者把这些 dll 所在路径加入系统 PATH否则运行时会提示找不到动态库。5. 避坑与排查MQTT 模块编译和连接中的常见问题5.1 现象qmake 报 “Unknown module(s) in QT: mqtt”原因qt_lib_mqtt.pri没有拷贝到mkspecs\modules目录或者拷贝的路径不对。qmake 在解析QT mqtt时会去mkspecs\modules下找对应的.pri文件找不到就报这个错。解决确认C:\Qt\Qt5.10.1\5.10.1\mingw53_32\mkspecs\modules\qt_lib_mqtt.pri存在。如果没有从编译目录的build\lib下重新拷贝一份。拷贝后最好关掉 Qt Creator 重新打开让 qmake 重新缓存。5.2 现象编译通过但运行时报 “缺少 Qt5Mqtt.dll”原因动态库没有放到可执行文件能找到的路径下。Windows 下 exe 加载 dll 的顺序是当前目录 → 系统目录 → PATH 环境变量。解决把Qt5Mqtt.dll拷贝到 exe 同级目录或者把C:\Qt\Qt5.10.1\5.10.1\mingw53_32\bin加入系统 PATH。我一般用 Qt Creator 的「构建套件」设置在「运行」配置里把 bin 目录加到 PATH 前面这样调试时也能找到。5.3 现象连接阿里云时返回 “Bad username or password”原因签名算法或时间戳不对。阿里云的 HMAC-SHA1 签名要求时间戳与服务器时间偏差不超过 15 分钟且拼接字符串的顺序必须严格按clientId、deviceName、productKey、timestamp排列。解决检查generatePassword函数里的拼接顺序确认时间戳用的是毫秒级 Unix 时间。另外注意 DeviceSecret 不要有多余空格。我踩过一次坑从控制台复制 DeviceSecret 时末尾带了一个换行符导致签名一直不对排查了半天。5.4 现象编译 MQTT 源码时 mingw32-make 报 “undefined reference toSSL_CTX_new”原因MQTT 模块默认可能启用了 TLS 支持但 minGW 环境下没有链接 OpenSSL 库。解决如果你不需要 TLS可以在 qmake 时加CONFIGno_ssl参数重新生成 Makefileqmake ..\qtmqtt.pro CONFIGno_ssl mingw32-make -j4如果需要 TLS就得先编译或获取 minGW 版本的 OpenSSL 库并在.pro里加上LIBS -lssl -lcrypto和对应的头文件路径。5.5 现象32 位和 64 位库混用导致崩溃原因QT5.10.1 的 minGW 套件有 32 位和 64 位两个版本如果你用 32 位的 qmake 编译了 MQTT 库却在 64 位套件里使用链接阶段可能通过但运行时因为指针长度不同直接崩溃。解决确认 Qt Creator 当前使用的构建套件是 32 位还是 64 位然后确保 MQTT 库、Qt 库、编译器三者位数一致。我一般会在项目.pro里加一行message($$QMAKE_HOST.arch)来打印当前架构避免搞混。6. 装完怎么验证一个最小可跑的 MQTT 连接 Demo验证这套环境是否真正跑通不需要复杂的业务逻辑。我习惯写一个最小 Demo连接阿里云物联网平台订阅一个 Topic然后手动在控制台发一条消息看能否收到。具体步骤如下。第一步在阿里云物联网平台控制台创建一个设备拿到三元组。第二步把上面的连接代码补全加上订阅和消息接收的回调。第三步编译运行观察输出。// 在 connected 信号里订阅 Topic 并发布一条测试消息 QObject::connect(client, QMqttClient::connected, []() { qDebug() Connected!; QString topic / productKey / deviceName /user/test; client.subscribe(topic); // 发布一条消息到物模型 Topic QString pubTopic /sys/ productKey / deviceName /thing/event/property/post; QByteArray payload R({id:1,version:1.0,params:{temperature:25.5}}); client.publish(pubTopic, payload); qDebug() Published test message; });运行后如果控制台输出Connected!和Published test message并且在阿里云物联网平台的「日志服务」里能看到这条消息说明整条链路已经通了。如果连接成功但发布失败检查 Topic 权限和物模型是否定义。我一般还会加一个断线重连的逻辑因为网络抖动在生产环境很常见QObject::connect(client, QMqttClient::disconnected, []() { qDebug() Disconnected, retrying in 3s...; QTimer::singleShot(3000, []() { client.connectToHost(); }); });从那以后我每次配完这套环境都会先跑一遍这个最小 Demo确认连接、订阅、发布三个环节都正常再开始写业务代码。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑