Skip to content

How to use the callbackHandler inside the library #107

Open

Description

@robertgregor

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

  1. fhessel commented on Dec 15, 2020

    @fhessel
    Owner

    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::bind like described here. I will try to keep up with PR/Issues during holidays.

  2. robertgregor commented on Dec 15, 2020

    @robertgregor
    Author

    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);

  3. fhessel commented on Dec 15, 2020

    @fhessel
    Owner

    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::bind specified 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 the req and res parameter of the bound function. Since we have two parameters, you need to have two placeholders.

  4. robertgregor commented on Dec 15, 2020

    @robertgregor
    Author

    OKi, yes, shall be like that:
    HTTPSCallbackFunction handler =
    std::bind(&RemoteHome::handleSPIFFS, this, std::placeholders::_1, std::placeholders::_2);

    Thanks!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions