paho mqtt c库在window上编译与使用

前言

最近在用正点原子的imx6ull板子做个小项目,用到了lvgl做gui和mqtt做物联网通信。打算先在window平台下写好lvgl界面以及mqtt相关的代码,再移植到imx6ull上。移植lvgl库和mqtt库到imx6ull上,网上都能查到。lvgl在window下的仿真运行,看正点原子的lvgl教程也有提供。
故记录一下把mqtt库在window平台下的编译,然后用Visual Studio运行测试程序。
最后再在codeblocks下运行测试。

正文

下载cmake

cmake官网下载地址 https://cmake.org/download
在这里插入图片描述

安装过程一路next,这里注意一下选上把CMake添加到系统环境变量
在这里插入图片描述

克隆paho mqtt c

https://github.com/eclipse/paho.mqtt.c克隆仓库
在这里插入图片描述

解压上面clone下来的代码,在根路径新建build文件夹,如下图
在这里插入图片描述

打开cmake gui软件,设好项目代码目录,build文件夹目录。点击 Configure
在这里插入图片描述

选择自己的Visual Studio版本,点击 Finish
在这里插入图片描述

CMAKE_INSTALL_PREFIX变量存放的是库安装路径,我这里直接用默认的。点击Generate,下面显示Generating done
在这里插入图片描述

搜索,以管理员身份打开cmd
在这里插入图片描述
先将路径更改到mqtt库代码的路径。我这里是放在下面图片的目录

cd 路径

在这里插入图片描述
执行命令

cmake --build build --target install

如出现如下提示,说cmake install错误,是因为没有用管理员身份运行命令,无法创建目录C:/Program Files (x86)/Eclipse Paho
在这里插入图片描述
管理员身份打开cmd,切换到代码路径,运行cmake --build build --target install
在这里插入图片描述

编译完成,去C:\Program Files (x86)\Eclipse Paho C能看到4个文件夹,bin文件夹存放着.dll文件,include文件夹是.h头文件,lib文件夹存放.lib文件
在这里插入图片描述

下面开始编写实验代码,新建一个vs工程

vs2022 项目设置

由于我在编译时cmake的CMAKE_INSTALL_PREFIX变量用的默认设置,在路径C:\Program Files (x86)\Eclipse Paho C,下面有关依赖的路径都基于这个路径。

.h头文件,.lib库文件目录

在这里插入图片描述
在这里插入图片描述

依赖的.lib

在这里插入图片描述

关联.dll目录

在这里插入图片描述

main.c 代码

代码基于正点原子imx6ull教程里面的mqtt示例

正点原子阿尔法Linux开发板(A盘)-> 09、文档教程 -> 【正点原子】I.MX6U嵌入式Linux C应用编程指南V1.4.pdf

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "MQTTClient.h" //包含MQTT客户端库头文件
#include <Windows.h>

/* ########################宏定义##################### */
#define BROKER_ADDRESS	"tcp://iot.ranye-iot.net:1883"	//然也物联平台社区版MQTT服务器地址

/* 客户端id、用户名、密码 *
 * 当您成功申请到然也物联平台的社区版MQTT服务后
 * 然也物联工作人员会给你发送8组用于连接社区版MQTT服务器
 * 的客户端连接认证信息:也就是客户端id、用户名和密码
 * 注意一共有8组,您选择其中一组覆盖下面的示例值
 * 后续我们使用MQTT.fx或MQTTool的时候 也需要使用一组连接认证信息
 * 去连接社区版MQTT服务器!
 * 由于这是属于个人隐私 笔者不可能将自己的信息写到下面 */
#define CLIENTID "alientek" // 客户端id
#define USERNAME ""         // 用户名
#define PASSWORD ""         // 密码

 /* 主题定义 */
#define WILL_TOPIC "win/will"   // 遗嘱主题
#define SUB_TOPIC "win/msg"   // esp32信息主题

int i = 0;

static int msgarrvd(void* context, char* topicName, int topicLen, MQTTClient_message* message)
{
    printf("[MQTT msg]:%s: %s\n", topicName, message->payload);
    /* 释放占用的内存空间 */
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

/* 连接服务器错误回调函数 */
static void connlost(void* context, char* cause)
{
    printf("\nConnection lost\n");
    printf("    cause: %s\n", cause);
}

int main(int argc, char* argv[])
{
    /****** MQTT ************/
    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    MQTTClient_willOptions will_opts = MQTTClient_willOptions_initializer;
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    int mqtt_rc;

    /* 创建mqtt客户端对象 */
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_create(&client, BROKER_ADDRESS, CLIENTID,
            MQTTCLIENT_PERSISTENCE_NONE, NULL)))
    {
        printf("Failed to create client, return code %d\n", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto exit;
    }

    /* 设置回调 */
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_setCallbacks(client, NULL, connlost,
            msgarrvd, NULL)))
    {
        printf("Failed to set callbacks, return code %d\n", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto destroy_exit;
    }

    /* 连接MQTT服务器 */
    will_opts.topicName = WILL_TOPIC; // 遗嘱主题
    will_opts.message = "offline";        // 遗嘱消息
    will_opts.retained = 1;               // 保留消息
    will_opts.qos = 0;                    // QoS0

    conn_opts.will = &will_opts;
    conn_opts.keepAliveInterval = 30; // 心跳包间隔时间
    conn_opts.cleansession = 0;       // cleanSession标志
    conn_opts.username = USERNAME;    // 用户名
    conn_opts.password = PASSWORD;    // 密码
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_connect(client, &conn_opts)))
    {
        printf("Failed to connect, return code %d\n", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto destroy_exit;
    }

    printf("MQTT服务器连接成功!\n");

    /* 发布上线消息 */
    pubmsg.payload = "online"; // 消息的内容
    pubmsg.payloadlen = 6;     // 内容的长度
    pubmsg.qos = 0;            // QoS等级
    pubmsg.retained = 1;       // 保留消息
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_publishMessage(client, WILL_TOPIC, &pubmsg, NULL)))
    {
        printf("Failed to publish message, return code %d\n", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto disconnect_exit;
    }

    /* 订阅主题 win/msg */
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_subscribe(client, SUB_TOPIC, 0)))
    {
        printf("Failed to subscribe, return code %d\n", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto disconnect_exit;
    }

    /* 向服务端发布信息 */
    for (;;)
    {
        MQTTClient_message tempmsg = MQTTClient_message_initializer;
        char temp_str[10] = { 0 };
        sprintf(temp_str, "%d", i);

        /* 发布累加变量信息 */
        tempmsg.payload = temp_str;            // 消息的内容
        tempmsg.payloadlen = strlen(temp_str); // 内容的长度
        tempmsg.qos = 0;                       // QoS等级
        tempmsg.retained = 1;                  // 保留消息
        if (MQTTCLIENT_SUCCESS !=
            (mqtt_rc = MQTTClient_publishMessage(client, "win/tmp", &tempmsg, NULL)))
        {
            printf("Failed to publish message, return code %d\n", mqtt_rc);
            mqtt_rc = EXIT_FAILURE;
            goto unsubscribe_exit;
        }

        Sleep(3000); // 每隔30秒 更新一次数据
        i++;
    }

unsubscribe_exit:
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_unsubscribe(client, SUB_TOPIC)))
    {
        printf("Failed to unsubscribe, return code %d\n", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
    }
disconnect_exit:
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_disconnect(client, 10000)))
    {
        printf("Failed to disconnect, return code %d\n", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
    }
destroy_exit:
    MQTTClient_destroy(&client);
exit:
    return mqtt_rc;
}

上面代码需要自己设置一下宏定义里面BROKER_ADDRESS服务器ip地址和端口, USERNAME用户名
PASSWORD密码。

测试效果

我这里使用MQTT Explorer软件,来查看程序发布的信息以及向程序发送消息。

代码会向遗嘱主题win/will,发送online或者offline,连接上MQTT服务器,MQTT Explorer就会看到主题win/will下显示online,程序退出或者掉线,win/will主题就会显示offline;
程序每隔3秒就会往win/tmp发送一个由0自加1的整数;
程序订阅了win/msg主题,用MQTT Explorer往这个主题发信息,程序就会收到,并打印在命令行。
在这里插入图片描述

codeblocks运行

我的clodeblocks版本为20.03
新建一个项目,在Project --> Build options.. --> Search directories配置

头文件路径

在这里插入图片描述

.dll路径和.lib路径

在这里插入图片描述

.lib路径

在这里插入图片描述

编译运行效果与在Visual Studio中运行一致。

参考链接

How to build paho mqtt c++ on windows - Stack Overflow
关于CMake(cmake-gui)的使用及注意事项,超详细!
codeblocks由于找不到zxing_dll.dll,无法继续执行代码
CodeBlocks导入第三方库的详细简单过程
codeblocks 使用第三方库

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值