前言

近期因为某个项目需要用到MQTT通信,开发环境Linux,使用C语言开发,起初使用官方提供的C语言版本库,源生库很不错,不过很多逻辑需要自己维护,我对MQTT熟悉程度不深,项目工作量巨大,一开始还觉得问题不大,后来才发现,自己维护msg接收经常无法收到消息。后准备改用mosquitto,在源码入口进行修改,就此分享我踩的一点坑。

mosquitto 安装步骤

直接上安装步骤,此处不做详细解释,可留言询问

$ sudo apt-get install libssl-dev libc-ares-dev libssl1.0-dev
$ wget http://mosquitto.org/files/source/mosquitto-1.3.4.tar.gz
$ tar zxfv mosquitto-1.3.4.tar.gz
$ cd mosquitto-1.3.4
$ make
$ sudo make install
$ sudo ln -s /usr/local/lib/libmosquitto.so.1/usr/lib/libmosquitto.so.1
$ sudo ldconfig

验证安装结果

$ mosquitto_sub

结论

上面的步骤已经成功安装mosquitt,理论上是可以自主开发了,可以先尝试用最简单的方法验证一下,把client文件夹下的sub_client.c文件复制出来,把入口main()函数该做一个API,再重新写一份主程序文件,尝试调用一下。本想传我的测试代码,这里就不多废话了,直接上结论了。

如果真的这样测试了,你会发现,根本收不到MQTT消息,怎么也收不到。除非把main函数写到sub_client.c文件里。

mosquitto,在编译得到libmosquitto.so.1的过程中,是没有加-fPIC的,科普一下

fPIC的目的是什么?共享对象可能会被不同的进程加载到不同的位置上,如果共享对象中的指令使用了绝对地址、外部模块地址,那么在共享对象被加载时就必须根据相关模块的加载位置对这个地址做调整,也就是修改这些地址,让它在对应进程中能正确访问,而被修改到的段就不能实现多进程共享一份物理内存,它们在每个进程中都必须有一份物理内存的拷贝。fPIC指令就是为了让使用到同一个共享对象的多个进程能尽可能多的共享物理内存,它背后把那些涉及到绝对地址、外部模块地址访问的地方都抽离出来,保证代码段的内容可以多进程相同,实现共享。

我们直接找到lib目录下的Makefile,第48行,增加 -fPIC,结果如下:

$(CC) -shared -fPIC $(LIB_LDFLAGS) $^ -o $@ ${LIB_LIBS}

重做一遍make和make install。