如何将成员函数作为回调参数传递给需要“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_membercbdata 参数现在可能无用,可以删除。

请记住,只要处理程序已注册,就让 HttpServer 实例保持活动状态。

另外,重申一下:这取决于我对您所展示的 API 的假设。仔细查阅文档。