MQTT library callback to message handler in a class

I am currently using a local callback function to forward incoming MQTT messages to a message handler that is a non-static member function. I modified one of the MQTT library example scripts to demonstrate how I am doing this. That code is below …

I’d like to find a way to eliminate the local callback function and have the MQTT library call the message handler directly. Is anyone aware of a way to do this?

#include <MQTT.h>

class X { // -------------------------------------------------------------- Added Class
  private:
  public:
    void mqttMsgHandler(char* topic, byte* payload, unsigned int length) {
        payload[length] = '\0';
        Particle.publish("MQTT Callback", (char*) payload, PRIVATE);
    }
}x;

// --------------------------- New callback function forwards message to x.mqttMsgHandler
void callback(char* topic, byte* payload, unsigned int length) {
    void (X::* callbackPointer) (char*,byte*, unsigned int) = &X::mqttMsgHandler; 
    (x.*callbackPointer) (topic, payload, length);
}



 // if want to use IP address,
 byte server[] = { 192,168,86,53 };
 MQTT client(server, 1883, callback);
 /* want to use domain name,
 * exp) iot.eclipse.org is Eclipse Open MQTT Broker: https://iot.eclipse.org/getting-started
 * MQTT client("iot.eclipse.org", 1883, callback);
 **/
//MQTT client("server_name", 1883, callback);

/* recieve message
void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;

    if (!strcmp(p, "RED"))
        RGB.color(255, 0, 0);
    else if (!strcmp(p, "GREEN"))
        RGB.color(0, 255, 0);
    else if (!strcmp(p, "BLUE"))
        RGB.color(0, 0, 255);
    else
        RGB.color(255, 255, 255);
    delay(1000);
}
*/

void setup() {
    RGB.control(true);

    // connect to the server
    client.connect("sparkclient");

    // publish/subscribe
    if (client.isConnected()) {
        client.publish("outTopic/message","hello world");
        client.subscribe("inTopic/message");
    }
}

void loop() {
    if (client.isConnected())
        client.loop();
}

Unless the MQTT library provides an overload that accepts non-static member functions (by taking the “local” function pointer and the instance pointer separately) there is no clean way.

Since C++ would allow objects to be relocated storing a non-static function pointer would be dangerous.

I am aware that C** objects can be moved on behest of application code. Does this statement imply that C++ can move objects on it's own volition?

C++ won’t do it on its own but the OS (think Windows, Linux, …) may well do.
If you have dynamic memory management, swap files and such things on your system the OS may swap your modules out and in of RAM without guarantee that it will end up at the same place in your physical nor virtual address space.
And for that reason C++ has rules in place that would prevent such issues even on devices lacking these high level features.

1 Like