// typedef from library that I cannot change
typedef int (*mg_request_handler)(mg_connection *conn, void *cbdata);
// this free function is for testing
int get_handler_free(struct mg_connection* conn, void* cbdata) {
//...
}
// this member function is what I want to use
int HttpServer::get_handler_member(struct mg_connection* conn, void* cbdata) {
//...
}
// inside this member function, the callback param is needed
void HttpServer::start() {
//...
// this way doesn't work
mg_request_handler get_handler = std::bind(&HttpServer::get_handler_member, this);
mg_set_request_handler(ctx_, "/get", get_handler, nullptr);
// this way works well
mg_request_handler get_handler = &get_handler_free;
mg_set_request_handler(ctx_, "/get", get_handler, nullptr);
//...
}
It is not possible to have a (non-member-) function pointer to a non-static member function. It is also not possible to point a function pointer to a bound function.
Notice how the free function type has an argument void *cbdata
. You haven't shown the documentation of the API that you use, but I would be willing to bet that the API follows a common idiom, and the third argument of mg_set_request_handler
is also void *cbdata
. If my assumption is correct, the same pointer that was passed to registration, will be passed to the handler later. It's purpose is to pass data - such as your HttpServer
instance into the callback.
For example:
mg_set_request_handler(ctx_, "/get", [](mg_connection *conn, void *cbdata) {
assert(cbdata);
HttpServer& server = *static_cast<HttpServer*>(cbdata);
server.get_handler_member(conn, cbdata);
}, this);
If get_handler_member
has non-public access, then you'll need to use a static member function instead of the lambda that I used in my example. Also, the cbdata
argument of get_handler_member
is now probably useless and can be removed.
Do remember to keep the HttpServer
instance alive as long as the handler is registered.
Also, to re-iterate: This relies on my assumption about the API that you've shown. Consult the documentation carefully.