PahoMQTT Назначить события - PullRequest
0 голосов
/ 13 июня 2018

Я использую Paho MQTT для C ++ и пытаюсь назначить методы класса как события.При назначении методов вне класса это работает, но при назначении их из класса я получаю следующие исключения:

In file included from /home/void/Documents/Projects/Manufacturer/Server.cpp:5:
/home/void/Documents/Projects/Manufacturer/Server.h:19:10: note: declared here
     void connectionLost(void *context, char *cause);
          ^~~~~~~~~~~~~~
/home/void/Documents/Projects/Manufacturer/Server.cpp:23:27: error: cannot convert ‘Server::onConnect’ from type ‘void (Server::)(void*, MQTTAsync_successData*)’ to type ‘void (*)(void*, MQTTAsync_successData*)’
     conn_opts.onSuccess = onConnect;
                           ^~~~~~~~~
/home/void/Documents/Projects/Manufacturer/Server.cpp:24:27: error: cannot convert ‘Server::onConnectFailure’ from type ‘void (Server::)(void*, MQTTAsync_failureData*)’ to type ‘void (*)(void*, MQTTAsync_failureData*)’
     conn_opts.onFailure = onConnectFailure;
                           ^~~~~~~~~~~~~~~~
/home/void/Documents/Projects/Manufacturer/Server.cpp: In member function ‘void Server::onConnect(void*, MQTTAsync_successData*)’:
/home/void/Documents/Projects/Manufacturer/Server.cpp:94:22: error: cannot convert ‘Server::onSubscribe’ from type ‘void (Server::)(void*, MQTTAsync_successData*)’ to type ‘void (*)(void*, MQTTAsync_successData*)’
     opts.onSuccess = onSubscribe;
                      ^~~~~~~~~~~
/home/void/Documents/Projects/Manufacturer/Server.cpp:95:22: error: cannot convert ‘Server::onSubscribeFailure’ from type ‘void (Server::)(void*, MQTTAsync_failureData*)’ to type ‘void (*)(void*, MQTTAsync_failureData*)’
     opts.onFailure = onSubscribeFailure;
                  ^~~~~~~~~~~~~~~~~~

Как я могу создать методы класса событий?

Server.cpp

#include "Server.h"

Server::Server(const char *manufacturerID) {
    this->manufacturerID = manufacturerID;

    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
    MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
    MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
    MQTTAsync_token token;
    int rc;
    int ch;

    MQTTAsync_create(&this->MQTTclient, "tcp://127.0.0.1:1883", manufacturerID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    MQTTAsync_setCallbacks(this->MQTTclient, NULL, connectionLost, messageArrived, NULL);

    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;

    conn_opts.onSuccess = onConnect;
    conn_opts.onFailure = onConnectFailure;
    conn_opts.context = this->MQTTclient;
    if ((rc = MQTTAsync_connect(this->MQTTclient, &conn_opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start connect, return code %d\n", rc);
        exit(-1);
    }

}



int Server::messageArrived(void *context, char *topicName, int topicLen, MQTTAsync_message *message)
{
    int i;
    char* payloadptr;

    printf("Message arrived\n");
    printf("     topic: %s\n", topicName);
    printf("   message: ");

    payloadptr = (char*) message->payload;
    for(i=0; i<message->payloadlen; i++)
    {
        putchar(*payloadptr++);
    }
    putchar('\n');
    MQTTAsync_freeMessage(&message);
    MQTTAsync_free(topicName);
    return 1;
}

void Server::connectionLost(void *context, char *cause)
{
    MQTTAsync client = (MQTTAsync)context;
    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
    int rc;

    printf("\nConnection lost\n");
    printf("     cause: %s\n", cause);

    printf("Reconnecting\n");
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;
    if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start connect, return code %d\n", rc);
        finished = 1;
        return;
    }
}

void Server::onConnectFailure(void* context, MQTTAsync_failureData* response)
{
    printf("Connect failed, rc %d\n", response ? response->code : 0);
    finished = 1;
}


void Server::onConnect(void* context, MQTTAsync_successData* response)
{
    MQTTAsync client = (MQTTAsync)context;
    MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
    MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
    int rc;

    printf("Successful connection\n");

    printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
           "Press Q<Enter> to quit\n\n", "SensorData", this->manufacturerID, 1);
    opts.onSuccess = onSubscribe;
    opts.onFailure = onSubscribeFailure;
    opts.context = client;

    deliveredtoken = 0;

    if ((rc = MQTTAsync_subscribe(client, "SensorData",1, &opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start subscribe, return code %d\n", rc);
        exit(-1);
    }
}

void  Server::onSubscribe(void* context, MQTTAsync_successData* response)
{
    printf("Subscribe succeeded\n");
    subscribed = 1;
}

void  Server::onSubscribeFailure(void* context, MQTTAsync_failureData* response)
{
    printf("Subscribe failed, rc %d\n", response ? response->code : 0);
    finished = 1;
}

Server.h

#ifndef MANUFACTURER_SERVER_H
#define MANUFACTURER_SERVER_H


#include <string>
#include <MQTTAsync.h>

class Server {
public:

    explicit Server(const char *manufacturerName);

    int messageArrived(void *context, char *topicName, int topicLen, MQTTAsync_message *message);

    void connectionLost(void *context, char *cause);

    void onConnectFailure(void *context, MQTTAsync_failureData *response);

    void onConnect(void *context, MQTTAsync_successData *response);

    void onSubscribe(void *context, MQTTAsync_successData *response);

    void onSubscribeFailure(void *context, MQTTAsync_failureData *response);
private:
    volatile MQTTAsync_token deliveredtoken;
    MQTTAsync MQTTclient;
    std::string manufacturerID;
    int finished = 0;
    int subscribed = 0;

};


#endif //MANUFACTURER_SERVER_H

Для справки, это библиотеки paho mqtt для C ++ и C:

https://github.com/eclipse/paho.mqtt.cpp

https://github.com/eclipse/paho.mqtt.c

1 Ответ

0 голосов
/ 13 июня 2018

Ожидается, что события будут указателем на статическую функцию, а не на метод класса.

Вы должны использовать контекст для хранения указателя на экземпляр класса Server:

MQTTAsync_setCallbacks(this->MQTTclient, this, connectionLost, messageArrived, NULL);

Определите статическую заглушку для пересылки обратного вызова в экземпляр:

static void onConnect(void *context, MQTTAsync_successData *response) {
    static_cast<Server*>(context)->onConnect(response);
}

И передайте эту статическую заглушку в качестве обратного вызова:

conn_opts.onSuccess = &Server::onConnect;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...