如何将成员函数作为回调参数传递给需要“typedef-ed”自由函数指针的函数?
How to pass a member function as callback param to a function that expects a `typedef-ed` free function pointer?
// 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);
//...
}
不可能有一个指向非静态成员函数的(非成员)函数指针。也不可能将函数指针指向绑定函数。
注意自由函数类型如何有一个参数 void *cbdata
。您没有显示您使用的 API 的文档,但我愿意打赌 API 遵循一个常见的习语,并且 mg_set_request_handler
的第三个参数也是 void *cbdata
。如果我的假设是正确的,传递给注册的相同指针稍后将传递给处理程序。它的目的是将数据 - 例如您的 HttpServer
实例传递到回调中。
例如:
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);
如果 get_handler_member
具有非 public 访问权限,那么您将需要使用静态成员函数而不是我在示例中使用的 lambda。此外,get_handler_member
的 cbdata
参数现在可能无用,可以删除。
请记住,只要处理程序已注册,就让 HttpServer
实例保持活动状态。
另外,重申一下:这取决于我对您所展示的 API 的假设。仔细查阅文档。
// 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);
//...
}
不可能有一个指向非静态成员函数的(非成员)函数指针。也不可能将函数指针指向绑定函数。
注意自由函数类型如何有一个参数 void *cbdata
。您没有显示您使用的 API 的文档,但我愿意打赌 API 遵循一个常见的习语,并且 mg_set_request_handler
的第三个参数也是 void *cbdata
。如果我的假设是正确的,传递给注册的相同指针稍后将传递给处理程序。它的目的是将数据 - 例如您的 HttpServer
实例传递到回调中。
例如:
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);
如果 get_handler_member
具有非 public 访问权限,那么您将需要使用静态成员函数而不是我在示例中使用的 lambda。此外,get_handler_member
的 cbdata
参数现在可能无用,可以删除。
请记住,只要处理程序已注册,就让 HttpServer
实例保持活动状态。
另外,重申一下:这取决于我对您所展示的 API 的假设。仔细查阅文档。