环境:
Ubuntu18.04
开发板:debian
交叉编译工具链:arm-linux-gnueabihf-gcc 8.3.0
Qt:Qt5.11.2
解决方案在文末,如不想看中间过程,可直接跳转到文末。
mqtt是一种工业物联网协议,可以用来连接阿里云、百度云、onenet等云端,应用广泛。
关于mqtt的使用,网上资料主要有以下几种:
1、STM32+ESP8266:这种方式主要是借助ESP8266模块来联网,至于mqtt协议基本上是要自己实现的。 也就是mqtt的报文需要自己去构建,好在mqtt的报文并不是很复杂,稍微研究一下也能理解。
2、Linux下使用官方sdk包,比如阿里云有提供阿里的sdk包,下载后调用它提供的接口来连接阿里云。
3、QT里移植mqtt:这种方式因为可以直接调用官方写好的接口,因此使用起来就简单多了,但是这个移植过程并不是那么简单。 这分为Windows端和Linux端。 Windows端就不说了,我主要说一下Ubuntu下和arm开发板上的移植。
移植也分为两种,一种是编译成动态链接库,一种是直接把mqtt官方源码包含进去自己的工程里面,然后一起编译。 我本人觉得要编译成库,然后配置环境变量什么的比较麻烦,还不如直接把源码包含进去。
先说Ubuntu下的移植:
这个我是参考网上的,Linux Qt下MQTT模块的导入(移植)
按照这篇博客来操作,实测有效,总结起来非常简单,就是下载源码,添加到自己的工程中,然后编译,编译出错的都是因为头文件包含的时候,应该把<>替换成"",这两种头文件包含的区别相信大家都很清楚。
这样就移植好了。 可以看到,在这里使用gcc编译可以通过,并且写个简单的测试代码,确实能连接云端
接下来说一下移植到arm端:
这部分网上的资料是真的少,搜索半天都找不到你想要的。
我们知道,要移植到arm开发板上面,需要使用交叉编译工具链,正常情况下,你写好的qt程序在主机Ubuntu上能运行,只要换成交叉编译工具编译,就可以放到开发板上运行了。
但是这里你这样做会发现报错。
提示QSslConfiguration这种类型不认识(未定义)。于是我就去找一下这个在哪里有定义,找了一下,发现这种类型其实在qsslconfiguration.h这个文件中是有定义的,但是前面通过#ifndef QT_NO_SSL这个宏没有把这段代码编译进去
于是真相大白了,在gcc里没有那个宏定义,所以下面那段代码会被编译,所以自然就不会出现未定义这种错误。但是当使用交叉编译工具链的时候,在qtnetwork-config.h这个文件中找到了这个宏定义,所以#ifndef QT_NO_SSL 到#endif之间的代码都不会被编译,自然QSslConfiguration就会未定义了。
于是我猜想,把qtnetwork-config.h中的这个QT_NO_SSL宏给注释掉,应该就可以了,虽然 说这样乱改代码可能导致一些意想不到的结果,但我还是想试一下看能不能编译通过。结果发现会出现一连串的连锁反应,改了这个,又会出现新的错误,所以这种方法不行。而且像这种文件它默认是只读的,也就是说它本来就不希望你去修改,所以不应该这样做。
后面我又想,既然直接改变宏定义不行,能不能把报错的地方直接注释掉,反正那些函数可能并没有用到,所以注释掉应该不会有什么影响
这里是报错的那个类的头文件,再切换到源文件
发现都是没有编译的,但是仔细观察源文件,其实也是有QT_NO_SSL这个宏的
这里就让人觉得很奇怪了,同样是有这个宏,其他的地方都不会被编译,这里却会被编译,而且其他地方都可以跳转到qtnetwork-config.h文件中去,这里却不会。
那么,很容易猜到,在这个源文件里没有包含qtnetwork-config.h这个头文件,导致没有定义那个宏。
解决办法:在qmqtt_ssl_socket_p.h文件中添加一句代码:
#include "qtnetwork-config.h"
问题成功解决。把编译好的文件放在arm开发板上,可以成功执行
至此,移植结束,可以尽情开发了。
全部0条评论
快来发表一下你的评论吧 !