Как передать функцию-член в качестве параметра обратного вызова функции, которая ожидает указатель на свободную функцию `typedef-ed`? - PullRequest
0 голосов
/ 15 октября 2018
// 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);

  //...
}

1 Ответ

0 голосов
/ 15 октября 2018

Невозможно иметь (не-член-) указатель функции на нестатическую функцию-член.Также невозможно указать указатель функции на связанную функцию.

Обратите внимание, что у типа свободной функции есть аргумент 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 имеет не публичный доступ, вынужно использовать статическую функцию-член вместо лямбды, которую я использовал в моем примере.Кроме того, аргумент cbdata get_handler_member теперь, вероятно, бесполезен и может быть удален.

Не забудьте сохранить экземпляр HttpServer живым, пока обработчик зарегистрирован.

Также, чтобы повторить: это зависит от моего предположения об API, который вы показали.Внимательно изучите документацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...