问题
I'm writing a class to access global variables through string-input (serial, webinterface, telnet, etc.) on an esp32. Therefore my variableAccess class has an attribute representing the variables address and an enum specifying the datatype (to make it short only int and float are in the example code below). The variable can then be set/read by the setValue/readValue methods. During initialization the variableAccess objects are created and stored in a vector 'allVariables'
Now for my problem: I want all those variableAccess-objects to provide a handler function 'wi_handle' which can then be passed to a WebServer method, but I'm getting errors because of an 'invalid use of non-static member function'. After doing some research I now understand why 'wi_handle' has to be static, but still I'm not sure how one would implement what i have to achieve (creating a subdomain and the corresponding handler on the webinterface).
My code:
#include <vector>
#include <locale>
#ifndef WebServer
#include <WebServer.h>
#endif
#ifndef server(80)
WebServer server(80);
#endif
enum ACCESS {NONE, READ, WRITE, READWRITE};
enum DATATYPE {INT,FLT};
class Variabel_Access {
public:
Variabel_Access(int *varPointer, String varName, ACCESS pAccess);
Variabel_Access(float *varPointer, String varName, ACCESS pAccess);
long int variablePointer;
String variableName;
ACCESS variableAccess;
DATATYPE datatype;
String readValue();
String setValue(String value);
//WI start
void wi_handle ();
//WI end
};
Variabel_Access::Variabel_Access (int* varPointer, String varName, ACCESS varAccess=READWRITE) {
variablePointer=(long int) varPointer;
variableName=varName;
variableAccess=varAccess;
datatype=INT;
}
Variabel_Access::Variabel_Access (float* varPointer, String varName, ACCESS varAccess=READWRITE) {
variablePointer=(long int) varPointer;
variableName=varName;
variableAccess=varAccess;
datatype=FLT;
}
String Variabel_Access::readValue () {
if (!(variableAccess==READ || variableAccess==READWRITE)) {
return "ERROR: no access";
}
switch(datatype) {
case INT:{
int& i = *reinterpret_cast<int*>(variablePointer);
return String(i);}
case FLT:{
float& f = *reinterpret_cast<float*>(variablePointer);
return String(f);}
default:{
return "ERROR: type error";}
}
}
String Variabel_Access::setValue (String valuestring) {
if (!(variableAccess==WRITE || variableAccess==READWRITE)) {
return "ERROR: no access";
}
String response="";
switch(datatype) {
case INT:{
int value = atoi(valuestring.c_str());
*(int*)(variablePointer)=value;
return "done";}
case FLT:{
float value = atof(valuestring.c_str());
*(float*)(variablePointer)=value;
return "done";}
default:{
return "ERROR: type error";}
}
}
void Variabel_Access::wi_handle () {
String value=readValue();
server.send(200, "text/plane", value);
}
std::vector<Variabel_Access> all_variables;
int integer_variable=100;
float float_variable=19.17;
void setup() {
all_variables.push_back( Variabel_Access( &integer_variable, "myInteger", READ) );
all_variables.push_back( Variabel_Access( &float_variable, "myFloat") );
for (int i=0; i<all_variables.size();i++) {
server.on("/"+all_variables[i].variableName, all_variables[i].wi_handle);
}
}
void loop() {
delay(10000);
}
Edit: webserver.on() as stated in WebServer.h:
typedef std::function<void(void)> THandlerFunction;
void on(const String &uri, THandlerFunction handler);
来源:https://stackoverflow.com/questions/52759758/how-to-pass-memberfunction-to-member-function-of-another-class