Paho mqtt c library is compiled and used on window

Foreword

Recently, I am working on a small project using the imx6ull board of Zhengdian Atom, using lvgl for GUI and mqtt for Internet of Things communication. I plan to write the lvgl interface and mqtt related code under the window platform first, and then transplant it to imx6ull. Port the lvgl library and mqtt library to imx6ull, which can be found online. For the simulation operation of lvgl under window, the lvgl tutorial of Zhengdian Atom is also provided.
Therefore, record the compilation of the mqtt library under the window platform, and then use Visual Studio to run the test program.
Finally, run the test under codeblocks.

Text

Download cmake

cmake official website download address https://cmake.org/download

Next in the installation process, please note that select Add CMake to the system environment variables

Clone paho mqtt c

Go to https://github.com/eclipse/paho.mqtt.c to clone the repository

Unzip the cloned code above and create a new build folder in the root path, as shown below

Open the cmake gui software, set the project code directory and the build folder directory. Click Configure

Select your Visual Studio version and click Finish

The CMAKE_INSTALL_PREFIX variable stores the library installation path. I use the default here. Click Generate, Generating done is displayed below

Search and open cmd as administrator

First change the path to the path of the mqtt library code. Here is the directory where I put the pictures below

cd path


Excuting an order

cmake --build build --target install

If the following prompt appears, saying cmake install error, it is because the command was not run as an administrator and the directory C:/Program Files (x86)/Eclipse Paho cannot be created.

Open cmd as an administrator, switch to the code path, and run cmake --build build --target install

Compilation is completed, go to C:\Program Files (x86)\Eclipse Paho C and you can see 4 folders. The bin folder stores the .dll file and the include folder It is a .h header file, and the lib folder stores .lib files.

Let’s start writing the experimental code and create a new vs project.

vs2022 project settings

Since I used the default setting of cmake’s CMAKE_INSTALL_PREFIX variable when compiling, in the path C:\Program Files (x86)\Eclipse Paho C, the following dependency paths are based on this path.

.h header file, .lib library file directory


Dependent.lib

Associated .dll directory

main.c code

The code is based on the mqtt example in the punctual atom imx6ull tutorial.

Punctual Atomic Alpha Linux Development Board (A Disk) -> 09. Documentation Tutorial -> [Just Atomic] I.MX6U Embedded Linux C Application Programming Guide 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" //Include MQTT client library header file
#include <Windows.h>

/* #######################Macro definition##################### * /
#define BROKER_ADDRESS "tcp://iot.ranye-iot.net:1883" //Ranye IoT Platform Community Edition MQTT server address

/* Client id, username, password *
 * After you successfully apply for the community version MQTT service of the Ranye IoT platform
 * Ranye IoT staff will send you 8 groups for connecting to the community version MQTT server
 * Client connection authentication information: that is, client id, username and password
 * Note that there are 8 groups in total, you choose one of them to cover the sample values below
 * When we use MQTT.fx or MQTTool later, we will also need to use a set of connection authentication information.
 * Go to connect to the community version MQTT server!
 * Since this is personal privacy, it is impossible for the author to write his own information below */
#define CLIENTID "alientek" // client id
#define USERNAME "" // Username
#define PASSWORD "" // Password

 /* Topic definition */
#define WILL_TOPIC "win/will" // Will topic
#define SUB_TOPIC "win/msg" // esp32 information topic

int i = 0;

static int msgarrvd(void* context, char* topicName, int topicLen, MQTTClient_message* message)
{<!-- -->
    printf("[MQTT msg]:%s: %s\
", topicName, message->payload);
    /* Release the occupied memory space */
    MQTTClient_freeMessage( & amp;message);
    MQTTClient_free(topicName);
    return 1;
}

/* Connection server error callback function */
static void connlost(void* context, char* cause)
{<!-- -->
    printf("\
Connection lost\
");
    printf(" cause: %s\
", 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;

    /* Create mqtt client object */
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_create( & amp;client, BROKER_ADDRESS, CLIENTID,
            MQTTCLIENT_PERSISTENCE_NONE, NULL)))
    {<!-- -->
        printf("Failed to create client, return code %d\
", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto exit;
    }

    /* Set callback */
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_setCallbacks(client, NULL, connlost,
            msgarrvd, NULL)))
    {<!-- -->
        printf("Failed to set callbacks, return code %d\
", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto destroy_exit;
    }

    /* Connect to MQTT server */
    will_opts.topicName = WILL_TOPIC; // Will topic
    will_opts.message = "offline"; // Will message
    will_opts.retained = 1; // Retain the message
    will_opts.qos = 0; // QoS0

    conn_opts.will = & amp;will_opts;
    conn_opts.keepAliveInterval = 30; // Heartbeat packet interval
    conn_opts.cleansession = 0; // cleanSession flag
    conn_opts.username = USERNAME; // Username
    conn_opts.password = PASSWORD; // Password
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_connect(client, & amp;conn_opts)))
    {<!-- -->
        printf("Failed to connect, return code %d\
", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto destroy_exit;
    }

    printf("MQTT server connection successful!\
");

    /* Publish online news */
    pubmsg.payload = "online"; // Content of the message
    pubmsg.payloadlen = 6; //The length of the content
    pubmsg.qos = 0; // QoS level
    pubmsg.retained = 1; // retain message
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_publishMessage(client, WILL_TOPIC, & amp;pubmsg, NULL)))
    {<!-- -->
        printf("Failed to publish message, return code %d\
", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto disconnect_exit;
    }

    /* Subscribe to topic win/msg */
    if (MQTTCLIENT_SUCCESS !=
        (mqtt_rc = MQTTClient_subscribe(client, SUB_TOPIC, 0)))
    {<!-- -->
        printf("Failed to subscribe, return code %d\
", mqtt_rc);
        mqtt_rc = EXIT_FAILURE;
        goto disconnect_exit;
    }

    /* Publish information to the server */
    for (;;)
    {<!-- -->
        MQTTClient_message tempmsg = MQTTClient_message_initializer;
        char temp_str[10] = {<!-- --> 0 };
        sprintf(temp_str, "%d", i);

        /* Publish accumulated variable information */
        tempmsg.payload = temp_str; //The content of the message
        tempmsg.payloadlen = strlen(temp_str); //The length of the content
        tempmsg.qos = 0; // QoS level
        tempmsg.retained = 1; // retain message
        if (MQTTCLIENT_SUCCESS !=
            (mqtt_rc = MQTTClient_publishMessage(client, "win/tmp", & tempmsg, NULL)))
        {<!-- -->
            printf("Failed to publish message, return code %d\
", mqtt_rc);
            mqtt_rc = EXIT_FAILURE;
            goto unsubscribe_exit;
        }

        Sleep(3000); //Update data every 30 seconds
        i + + ;
    }

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

The above code requires you to set the BROKER_ADDRESS server ip address and port in the macro definition, and USERNAME the user name.
, PASSWORD password.

Test effect

I use the MQTT Explorer software here to view the information published by the program and send messages to the program.

The code will send online or offline to the will topic win/will, connect to the MQTT server, and MQTT Explorer will see online displayed under the topic win/will, and the program will exit or If offline, the win/will theme will display offline;
The program will send an integer from 0 to 1 to win/tmp every 3 seconds;
The program subscribes to the win/msg topic. Use MQTT Explorer to send a message to this topic, and the program will receive it and print it on the command line.

codeblocks run

My clodeblocks version is 20.03
Create a new project and configure it in Project --> Build options.. --> Search directories

Header file path

.dll path and .lib path

.lib path

The compilation and running effect is the same as running in Visual Studio.

Reference link

How to build paho mqtt c++ on windows – Stack Overflow
Super detailed information on the use and precautions of CMake (cmake-gui)!
codeblocks cannot continue to execute the code because it cannot find zxing_dll.dll.
Detailed and simple process of importing third-party libraries into CodeBlocks
codeblocks uses third-party libraries