Loading...
首页专栏正文

【海思HI3520之QT开发】-网络通讯实战(一):利用QtMqtt编译成库实现MQTT

MacianYuan 发布于 2021-01-13 10:54:40 浏览 2673 点赞 97 收藏 8

环境: Ubuntu 12.04-64bit 硬件平台: Hi3520D_V300 内核版本: linux-3.0.y Qt版本: qt5.12.7 编译器: arm-hisiv300-linux-gcc 作者: MacianYuan 原文链接(易佰纳ebaina.com):https://www.ebaina.com/articles/140000005387 摘要:使用Mqtt连接电信云或者阿里云,电信云是标准的mqtt服务端,阿里云需要通过三要素才能连接到阿里的mqtt服务端。无论是哪一种首先需要下载qt官方提供的MQTT源码。

第一节:下载源码

源码地址:https://github.com/qt/qtmqtt

1、注意:选择版本与qt版本不一致可能导致编译出错和不兼容的情况。因为我的qt版本是qt5.12.7,所以也选择5.12.7。

2、查看qtmqtt工程源码

root@ubuntu:/home/macian/mqtt# cd qtmqtt-5.12.7
root@ubuntu:/home/macian/mqtt/qtmqtt-5.12.7# ls
dist      LICENSE.GPL3         qtmqtt.pro       src           tests
examples  LICENSE.GPL3-EXCEPT  qtmqtt.pro.user  sync.profile

3、使用 arm-hisiv300-linux-gcc 交叉变异的qt源码生成的qmake 交叉编译:

4、编译过程会出现没有没有找到qtmqtt相关头文件的情况,这是没有找到qtmqtt的相关头文件:

/home/macian/Project/mqtt/qtmqtt-5.12.7/src/mqtt/qmqttauthenticationproperties.h:33: error: QtMqtt/qmqttglobal.h: No such file or directory

6、在使用arm-hisiv300-linux-gcc交叉编译qt5 ,qmake安装目录的include中创建QtMqtt文件夹

sudo mkdir QtMqtt

7、把源码中的.h头文件拷贝到文件夹中

sudo cp /home/macian/Project/mqtt/qtmqtt-5.12.7/src/mqtt/*.h QtMqtt/

8、ls查看拷贝结果如下

9、再次编译即可编译成功,到编译生成目录中查看编译生成文件。

10、在进入lib目录下查看需要的lib库文件,即完成编译hi3520V300平台可使用的qtmqtt lib库。

第二节:错误解决

如果使用版本不一致,可能由于版本过高,或者与ubuntu版本不兼容原因可能会出现以下错误。

  • 错误一: 重新构建,仍然报错缺少 QtMqtt/QMqttClient等头文件,将报错的工程头文件替换
  • 解决方法:
将
#include <QtMqtt/QMqttClient>
改成
#include <QtMqtt/qmqttclient.h>

将
#include <QtMqtt/QMqttSubscription>
改成
#include <QtMqtt/qmqttsubscription.h>

将
#include <QMqttTopicName>
改成
#include <QtMqtt/qmqtttopicname.h>

将
#include <QtMqtt/QMqttMessage>
改成
#include <QtMqtt/qmqttmessage.h>
  • 错误二:

    qtmqtt/src/mqtt/qmqttconnection.cpp:169: error: ‘errorOccurred’ is not a member of ‘QAbstractSocket’
     connect(socket, &QAbstractSocket::errorOccurred, this, &QMqttConnection::transportError);
  • 解决方法: 将下面源代码 connect(socket, &QAbstractSocket::errorOccurred, this, &QMqttConnection::transportError); 改成以下内容 connect(socket, static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)> (&QAbstractSocket::error), this, static_cast<void(QMqttConnection::*)(QAbstractSocket::SocketError)>(&QMqttConnection::transportError) );

  • 错误三:

    qmqtttopicname.cpp:148: error: C2039: “KeepEmptyParts”: 不是“Qt”的成员
  • 解决方法: 将下面源代码 return d->name.split(QLatin1Char('/'), Qt::KeepEmptyParts); 改写成: return d->name.split(QLatin1Char('/'), QString::KeepEmptyParts);

  • 错误四:

    qmqtttopicname.cpp:189: error: call to 'qHash' is ambiguous
  • 解决方法: 将下面源代码: return qHash(name.d->name, seed); 改为: return qHash(static_cast<QString>(name.d->name), static_cast<uint>(seed));

第三节 应用到项目工程中

真正用到项目中,还需要以下操作才可以 一、需要将交叉编译生成的lib库 加入到项目工程当中 在QT工程中创建include 和lib 目录

  • 将lib库加入到项目当中, cp ../../mqtt/build-qtmqtt-Qt_5_12_7_hisiv300-Debug/lib/libQt5Mqtt.* .
  • 将头文件加入到头文件当中, cp /home/macian/Tools/qt/qt-everywhere-src-5.12.7/_install/include/QtMqtt . -rf

二、需要将lib库拷贝到板子的lib库中,否则运行会报错找不到mqtt库。 通过nfs 挂载或者u盘的方式 ,或者直接将lib库添加到文件系统烧写进去。 建议直接拷贝到交叉编译的qt库当中,这样可以直接使用,就不用再配置环境变量了。

第四节 总结

1、由于此次使用的版本是Qt5.12.7,所以可以直接使用qt官方的mqtt库,因为qt没有加入到qt源码当中,才会如此麻烦。

2、因为Qt官方提供的Mqtt仅支持5.10之后的qt版本,如果遇到当前使用qt5版本不高的情况,又不想更改qt版本的情况,这边可以使用另外一个mqtt开源项目进行移植。 源码地址: https://github.com/emqx/qmqtt 这个版本需要注意:

  • 此项目仍然需要Qt>=5.3 以上的版本才可以。
  • 默认情况下启用SSL,如果OpenSSL的版本<1.0.2,则可能不支持SSL。 禁用CMakeLists.txt(Cmake)中的SSL: option( ${PROJECT_NAME}_SSL "Enable SSL support for MQTT" OFF ) 使用src/mqtt/qmqtt.pro(Qmake)禁用SSL: CONFIG+=QMQTT_NO_SSL
  • 要添加webSocket支持,请编译Qt>=5.7版本以上才可以, 并且需要指定‘config+=QMQTT_WebSocket’。

3、如果遇到qt5.3以下版本,甚至qt4版本的情况,又不想改成qt5该如何选择,这边我有一个建议:进入阿里云或者电信云的官网,使用阿里云或者电信云官方的SDK进行移植使用,测试是可行的。

曾梦想仗剑天涯,后来项目太多没去。。。 关注我,用最小的篇幅分享实用的项目实战

*本文仅代表作者观点,不代表易百纳技术社区立场。系作者授权易百纳技术社区发表,未经许可不得转载。

精彩评论

内容存在敏感词
打赏
打赏作者
MacianYuan
您的支持将鼓励我继续创作!
金额:
¥1 ¥5 ¥10 ¥50 ¥100
支付方式:
微信支付
支付宝支付
微信支付
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

易百纳技术社区
确定要删除此文章、专栏、评论吗?
确定
取消
易百纳技术社区