1

I am using the PubSubClient library in my own Arduino library. I'm having trouble with trying to assign a class member as the client library setCallback callback function.

MyClass.cpp:

#include <PubSubClient.h>
#include <Wifi.h>
#include "Arduino.h"
#include "MyClass.h"

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

void MyClass::connect(String host, int port) {
  mqttClient.begin(host, port, "/");
  mqttClient.setCallback(incomingEventHandler);
}

void MyClass::loop() {
  mqttClient.loop();
}

void MyClass::incomingEventHandler(char* type, byte *payload, unsigned int length) {
  // do stuff with incoming data
  // need to access other member functions and class variables
}

MyClass.h:

#ifndef MyClass_h
#define MyClass_h

#include <PubSubClient.h>
#include <Wifi.h>
#include "Arduino.h"

class MyClass {
  public:
    void connect(String host, int port);
    void loop();
    void incomingEventHandler(WStype_t type, uint8_t *payload, size_t length);
};

#endif

Error I see is:

sketch/MyClass.cpp: In member function 'void MyClass::connect(String, int)': MyClass.cpp:14:47: error: no matching function for call to 'PubSubClient::setCallback()'
mqttClient.setCallback(incomingEventHandler);

If I move the incomingEventHandler function outside the class definition, it works as expected, however then I can't call other class members or access class properties in the same scope.

In arduino c++ how can I pass non-static class member properties as a callback? Is there a better way to approach this?

P.S. This code is only to show the intent. It might not be compile too. There was a similar question like this at: How to pass non-static class member to callback?

but this is for esp-8266 and this is for avrmega4809 based board.

1
  • Personally I usually write a small wrapper that calls a function on a global object. Either as a normal function or as a static function if I only ever need one instance. Crude, but effective.
    – Majenko
    Mar 23, 2022 at 14:38

1 Answer 1

2

You can't. On the AVR platform, PubSubClient::setCallback() expects a raw function pointer as a callback, and that is what you have to provide. A static method is equivalent to a raw function, a non-static method is not, and neither are a functor or an std::function.

If you need more that one MyClass object, one solution might be to modify the pubsubclient library in order for it to store a pointer to your MyClass instance, and pass this pointer to your callback. If you never have to instances of MyClass subscribe to the same topic, a better solution might be to statically store a map from topics to MyClass instances and, within the callback, use this map to find the appropriate instance.

1
  • Technically you can do it, but not without changing the library. Easiest way would be pure virtual interface class definition and inherit from it and override callback method. Another way would be tutorialspoint.com/… (similar changes as the first way)
    – KIIV
    Mar 23, 2022 at 19:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.