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 Answers1

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.

Edgar Bonet
  • 45,094
  • 4
  • 42
  • 81