Repository navigation
How to use the callbackHandler inside the library #107
Description
Hi,
I have maybe similar issue as the others here.
I have a arduino library where I have a class, in which I want to use the handler:
RemoteHome.h
class RemoteHome {
public:
void handleSPIFFS(HTTPRequest * req, HTTPResponse * res);
}
Then in the RemoteHome.cpp I have:
void RemoteHome::handleSPIFFS(HTTPRequest * req, HTTPResponse * res) {
....
}
And I have in that class the method:
void RemoteHome::startWebServer() {
server = new HTTPServer();
ResourceNode *spiffsNode = new ResourceNode("", "", &RemoteHome::handleSPIFFS);
server->setDefaultNode(spiffsNode);
server->start();
if (server->isRunning()) {
LogTool::logSketch('I', PSTR("RemoteHome::setup"), PSTR("Http server is ready."));
}
Looks fine to me, but it will not compile:
Error downloading https://downloads.arduino.cc/packages/package_index.json
C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\RemoteHome\src\RemoteHome.cpp: In member function 'void RemoteHome::startWebServer()':
C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\RemoteHome\src\RemoteHome.cpp:788:68: error: no matching function for call to 'httpsserver::ResourceNode::ResourceNode(const char [1], const char [1], void (RemoteHome::)(httpsserver::HTTPRequest, httpsserver::HTTPResponse*))'
spiffsNode = new ResourceNode("", "", &RemoteHome::handleSPIFFS);
^
In file included from C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\esp32_https_server\src/HTTPServer.hpp:20:0,
from C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\esp32_https_server\src/HTTPSServer.hpp:15,
from C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\RemoteHome\src\RemoteHome.h:13,
from C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\RemoteHome\src\RemoteHome.cpp:9:
C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\esp32_https_server\src/ResourceNode.hpp:18:3: note: candidate: httpsserver::ResourceNode::ResourceNode(const string&, const string&, void ()(httpsserver::HTTPRequest, httpsserver::HTTPResponse*), const string&)
ResourceNode(const std::string &path, const std::string &method, const HTTPSCallbackFunction * callback, const std::string &tag = "");
^
C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\esp32_https_server\src/ResourceNode.hpp:18:3: note: no known conversion for argument 3 from 'void (RemoteHome::)(httpsserver::HTTPRequest, httpsserver::HTTPResponse*)' to 'void ()(httpsserver::HTTPRequest, httpsserver::HTTPResponse*)'
C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\esp32_https_server\src/ResourceNode.hpp:16:7: note: candidate: httpsserver::ResourceNode::ResourceNode(const httpsserver::ResourceNode&)
class ResourceNode : public HTTPNode {
^
C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\esp32_https_server\src/ResourceNode.hpp:16:7: note: candidate expects 1 argument, 3 provided
How can I make it working? Seems to me, that your code doesn't accept my method...
Activity
fhessel commentedon Dec 15, 2020
Hi,
it's the same issue as in #90 or #105: If you want to use a method from a class, you need to somehow specify on which instance that method should be called. You can do such things with
std::bind, but in 1.0.0, you cannot pass the result from that to the ResourceNode.If you need that functionality now, switch from master to PR #91 as mentioned in this comment and use
std::bindlike described here. I will try to keep up with PR/Issues during holidays.robertgregor commentedon Dec 15, 2020
Hi, Yes, this I did: esp32_https_server-feature-functional-callbacks.
But how can use std::bind?
I have tried this:
HTTPSCallbackFunction handler = std::bind(&RemoteHome::handleSPIFFS, std::placeholders::_1);
server->registerNode(new ResourceNode("/", "GET", handler));
But I have this error:
c:\users\gregorro\appdata\local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\xtensa-esp32-elf\include\c++\5.2.0\functional:1426:7: error: static assertion failed: Wrong number of arguments for pointer-to-member
static_assert(_Varargs::value
^
C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\RemoteHome\src\RemoteHome.cpp: In member function 'void RemoteHome::startWebServer()':
C:\RH\Sources\RH\RemoteHomeArduinoSketches\WiFi_ESP32\libraries\RemoteHome\src\RemoteHome.cpp:790:20: error: conversion from 'std::_Bind_helper<false, void (RemoteHome::)(httpsserver::HTTPRequest, httpsserver::HTTPResponse*), const std::_Placeholder<1>&>::type {aka std::_Bind<std::_Mem_fn<void (RemoteHome::)(httpsserver::HTTPRequest, httpsserver::HTTPResponse*)>(std::_Placeholder<1>)>}' to non-scalar type 'httpsserver::HTTPSCallbackFunction {aka std::function<void(httpsserver::HTTPRequest*, httpsserver::HTTPResponse*)>}' requested
std::bind(&RemoteHome::handleSPIFFS, std::placeholders::_1);
fhessel commentedon Dec 15, 2020
You need to stick to the exact syntax from the other PR.
Somewhere outside any function:
// Create a global instance of the RemoteHome class RemoteHome myRemoteHome;In your
setup()or whereever you configure your server:HTTPSCallbackFunction handler = std::bind(&RemoteHome::handleSPIFFS, &myRemoteHome, std::placeholders::_1, std::placeholders::_2); server.registerNode(new ResourceNode("/", "GET", handler));The first parameter of
std::bindspecified the function that should be called. The second parameter is a pointer to the instance on which it should be called (you also need to create such an instance, and make sure that it's valid for the whole lifetime of the server. That's why we created it in global scope above). The third and fourth parameters are placeholders. They will become thereqandresparameter of the bound function. Since we have two parameters, you need to have two placeholders.robertgregor commentedon Dec 15, 2020
OKi, yes, shall be like that:
HTTPSCallbackFunction handler =
std::bind(&RemoteHome::handleSPIFFS, this, std::placeholders::_1, std::placeholders::_2);
Thanks!!!