How to pass a object member function to ResourceNode constructor?
I need to register a node callback with a object member function I created a class to hold all my https request callbacks functions and I want to pass those functions to ResourceNode constructor and register in my server.
Some of my files
https_handler.h
#ifndef HTTPS_HANDLER_H
#define HTTPS_HANDLER_H
#include "Arduino.h"
#include <HTTPSServer.hpp>
#include "SSLCert.hpp"
#include <HTTPRequest.hpp>
#include <HTTPResponse.hpp>
using namespace httpsserver;
class HttpsHandler {
public:
HttpsHandler();
~HttpsHandler();
void root(HTTPRequest * req, HTTPResponse * res);
private:
};
#endif
https_handler.cpp
#include "https_handler.h"
void HttpsHandler::root(HTTPRequest * req, HTTPResponse * res) {
// We want to deliver an HTML page, so we set the content type
res->setHeader("Content-Type", "text/html");
// The response implements the Print interface, so you can use it just like
// you would write to Serial etc.
res->println("<!DOCTYPE html>");
res->println("<html>");
res->println("<head><title>Hello World!</title></head>");
res->println("<body>");
res->println("<h1>Hello World!</h1>");
res->print("<p>... from your ESP32!</p>");
res->println("</body>");
res->println("</html>");
}
my_server.h
#ifndef MY_SERVER_H
#define MY_SERVER_H
#include "../ssl_certificate/cert.h"
#include "../ssl_certificate/private_key.h"
#include "handlers/https_handler.h"
#include <HTTPSServer.hpp>
#include "SSLCert.hpp"
#include <HTTPRequest.hpp>
#include <HTTPResponse.hpp>
using namespace httpsserver;
class MyServer {
public:
MyServer();
~MyServer();
void setup();
void loop();
private:
SSLCert cert = SSLCert(
example_crt_DER, // DER-formatted certificate data
example_crt_DER_len, // length of the certificate data
example_key_DER, // private key for that certificate
example_key_DER_len // Length of the private key
);
HTTPSServer secureServer = HTTPSServer(&cert);
HttpsHandler *handler;
void configureNodes();
};
#endif
my_server.cpp
#include "my_server.h"
MyServer::MyServer(/* args */) { }
MyServer::~MyServer() { }
void MyServer::setup() {
Serial.println("MyServer::start");
secureServer.start();
configureNodes();
};
void MyServer::loop() {
secureServer.loop();
}
void MyServer::configureNodes() {
ResourceNode * nodeRoot = new ResourceNode("/", "GET", &HttpsHandler::root);
secureServer.registerNode(nodeRoot);
}
platformio.ini
[env:development]
platform = [email protected]
board = esp32doit-devkit-v1
framework = arduino
upload_speed = 115200
board_build.flash_mode = dio
build_flags =
-DHTTPS_LOGLEVEL=2
-DHTTPS_LOGTIMESTAMP
-DHTTPS_DISABLE_SELFSIGNING
lib_deps =
fhessel/esp32_https_server
Here the error logs
src/system/communication/protocols/HTTPS/my_server.cpp:23:77: error: no matching function for call to 'httpsserver::ResourceNode::ResourceNode(const char [2], const char [4], void (HttpsHandler::*)(httpsserver::HTTPRequest*, httpsserver::HTTPResponse*))'
ResourceNode * nodeRoot = new ResourceNode("/", "GET", &HttpsHandler::root);
^
In file included from .pio/libdeps/esp01_1m/esp32_https_server/src/HTTPServer.hpp:20:0,
from .pio/libdeps/esp01_1m/esp32_https_server/src/HTTPSServer.hpp:15,
from src/system/communication/protocols/HTTPS/handlers/https_handler.h:4,
from src/system/communication/protocols/HTTPS/my_server.h:6,
from src/system/communication/protocols/HTTPS/my_server.cpp:1:
.pio/libdeps/esp01_1m/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 = "");
^
.pio/libdeps/esp01_1m/esp32_https_server/src/ResourceNode.hpp:18:3: note: no known conversion for argument 3 from 'void (HttpsHandler::*)(httpsserver::HTTPRequest*, httpsserver::HTTPResponse*)' to 'void (*)(httpsserver::HTTPRequest*, httpsserver::HTTPResponse*)'
.pio/libdeps/esp01_1m/esp32_https_server/src/ResourceNode.hpp:16:7: note: candidate: httpsserver::ResourceNode::ResourceNode(const httpsserver::ResourceNode&)
class ResourceNode : public HTTPNode {
^
.pio/libdeps/esp01_1m/esp32_https_server/src/ResourceNode.hpp:16:7: note: candidate expects 1 argument, 3 provided
*** [.pio/build/esp01_1m/src/system/communication/protocols/HTTPS/my_server.cpp.o] Error 1
Is it possible to do what I am proposing? how? I'm a beginner in CPP
thanks in advance
ESP32-D0WDQ6 (revision 1)
- Flash Size: 4MB
Tools
- IDE and Version: vscode 1.51.1
- OS: Ubuntu 18.04.4 LTS
That won't work with the current release version, but #91 enables it when merged.
However, you cannot use your class method without an instance. So at some point, you need to create an instance of your HttpsHandler.
If that instance is called myHandler, the code would look like this:
// At the top of your sketch:
#include <HTTPSCallbackFunction.hpp>
// In your setup code:
HTTPSCallbackFunction handler =
std::bind(&HttpsHandler::root, &myHandler, std::placeholders::_1, std::placeholders::_2);
server.registerNode(new ResourceNode("/", "GET", handler));
A bit simplified, using bind creates a pointer to that root method that knows on which instance it should be executed. The placeholders allow to pass-through the req and res parameters.
#90 has more details on this.
Thanks for the quick response! Do you have any predictions of when the PR will be merged? I tested the PR branch and it worked perfectly!
Thanks for testing and giving feedback! I'm currently working on building a reliable, automated, and hardware-based CI pipeline for this repository, since I want to be sure that after merging a PR the examples still work (not only that they are able to build) and to be able to test all functionality in isolation. Doing that manually for each PR takes me some hours each time I'm merging something, which makes it hard to merge even little changes.
For that reason I decided to prioritize working on the CI first instead of spending my (currently quite limited) spare time on manual testing – that's also the reason why most issues are stale at the moment. I hope to get everything running around Christmas, and then merging PRs and working on issues should be easier and be doable with more confidence in the codebase.
If I don't stumble upon any issues with the way the PR is implemented, it will stay as it is. So you could in theory start working on the PR branch, since the only code changes to 1.0.0 are the ones required for implementing the callbacks, all other commits are just documentation, and when 1.1.0 is out, you could switch back to using normal semver.
Excellent decision! I will continue using the pr branch and awaiting the merge.
Thank you very much for your attention! I hope to be able to contribute to the community as I progress in my studies.