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.
-
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– Majenko2022年03月23日 14:38:37 +00:00Commented Mar 23, 2022 at 14:38
1 Answer 1
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.
-
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– KIIV2022年03月23日 19:43:10 +00:00Commented Mar 23, 2022 at 19:43
Explore related questions
See similar questions with these tags.