I am using the arduinoWebSockets library in my own Arduino library. I'm having trouble with trying to assign a class member as the websocket library onEvent
callback function.
MyClass.cpp:
#include <WebSocketsClient.h>
#include "Arduino.h"
#include "MyClass.h"
void MyClass::connect(String host, int port) {
webSocket.begin(host, port, "/");
webSocket.setReconnectInterval(5000);
// tried all these variations
// webSocket.onEvent(incomingEventHandler);
// webSocket.onEvent(MyClass::incomingEventHandler);
webSocket.onEvent(this->incomingEventHandler);
}
void MyClass::loop() {
webSocket.loop();
}
void MyClass::incomingEventHandler(WStype_t type, uint8_t *payload, size_t length) {
// do stuff with incoming data
// need to access other member functions and class variables
}
MyClass.h:
#ifndef MyClass_h
#define MyClass_h
#include <WebSocketsClient.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);
private:
WebSocketsClient webSocket;
};
#endif
The error returned is:
sketch/MyClass.cpp: In member function 'void MyClass::connect(String, int)': MyClass.cpp:14:47: error: no matching function for call to 'WebSocketsClient::onEvent()'
webSocket.onEvent(this->incomingEventHandler);
From what I understand it seems like I need to create a pointer to the class member, I have tried a few different ways, this one seemed the most promising, but still failed:
typedef void (MyClass::*MyClassMemFn)(WStype_t type, uint8_t *payload, size_t length);
void MyClass::connect(String host, int port) {
webSocket.begin(host, port, "/");
webSocket.setReconnectInterval(5000);
MyClassMemFn onEventCallback = &MyClass::incomingEventHandler;
webSocket.onEvent(MyClassMemFn onEventCallback);
}
The above returns this error:
sketch/MyClass.cpp: In member function 'void MyClass::connect(String, int)': MyClass.cpp:15:34: error: expected primary-expression before 'onEventCallback' webSocket.onEvent(MyClassMemFn onEventCallback);
I have also tried to use std::bind
:
void MyClass::connect(String host, int port) {
webSocket.begin(host, port, "/");
webSocket.setReconnectInterval(5000);
webSocket.onEvent(std::bind(&MyClass::incomingEventHandler, this));
}
Error:
sketch/MyClass.cpp: In member function 'void MyClass::connect(String, int)': MyClass.cpp:12:47: error: no matching function for call to 'WebSocketsClient::onEvent()'
webSocket.onEvent(this->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?
this
. Member functions have a "hidden" parameter.This
is necessary to allow access to the member data and virtual function table. The short answer to your question is therefore - a callback cannot be a member function.