首页 > 技术知识 > 正文

环境: 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。

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

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 交叉编译:

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

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查看拷贝结果如下 【海思HI3520之QT开发】-网络通讯实战(一):利用QtMqtt编译成库实现MQTT2

9、再次编译即可编译成功,到编译生成目录中查看编译生成文件。 【海思HI3520之QT开发】-网络通讯实战(一):利用QtMqtt编译成库实现MQTT3

10、在进入lib目录下查看需要的lib库文件,即完成编译hi3520V300平台可使用的qtmqtt lib库。 【海思HI3520之QT开发】-网络通讯实战(一):利用QtMqtt编译成库实现MQTT4

第二节:错误解决

如果使用版本不一致,可能由于版本过高,或者与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进行移植使用,测试是可行的。

阿里云物联网平台 https://iot.console.aliyun.com 电信云使能平台 https://www.ctwing.cn

猜你喜欢