Ошибка приведения к передаче пустой функции с пространством имен

Я пытаюсь обернуть в класс C ++ сервер, который я написал, используя мангуста (библиотека C). Проблема в том, что я пытаюсь передать функцию ev_handler к mg_create_server(), которые создают экземпляр сервера в мангусте. Но это дает ошибку приведения, я верю:

src/Server.cpp:16:44: error: cannot convert 'Server::ev_handler' from
type 'int (Server::)(mg_connection*, mg_event)' to type 'mg_handler_t
{aka int (*)(mg_connection*, mg_event)}'   server =
mg_create_server(NULL, ev_handler);

Я пытался сделать ev_handler статично, но имеет send_index_page(conn) это должно быть внутри класса-обёртки … Есть идеи?

void Server::start() {
struct mg_server *server;
int numberOfObjects;
_application = new Application();
_application->start();

// Create and configure the server
server = mg_create_server(NULL, ev_handler);

//... more code here ...
}

int Server::ev_handler(struct mg_connection *conn, enum mg_event ev) {
switch (ev) {
case MG_AUTH:     return MG_TRUE;
case MG_REQUEST:  return send_index_page(conn);
default:          return MG_FALSE;
}
}

1

Решение

Ваша проблема в том, что вы передаете функцию-член C ++ параметру, который хочет указатель на свободную функцию.

Mongoose является C API, и все его параметры обратного вызова являются функциями стиля C, которые в C ++ являются свободными (не участвующими) функциями.

Указатель на функцию-член отличается от указателя на свободную функцию тем, что ему нужен this или объект, для которого вызывается метод, для вызова.

В вашем случае вы передаете указатель функции-члена на Server учебный класс.

При взаимодействии с какими API C обычно передают void* объект контекста, который затем передается обратному вызову. Затем вы передаете указатель на свободную функцию или метод статического класса (который не имеет this и поэтому может работать с C API). Когда вызывается обратный вызов, вы затем приводите объект контекста к правильному типу и вызываете функцию-член, чтобы вернуться в контекст объекта. Я не вижу такого объекта в Мангусте. Возможно это там, и я просто не нахожу это.

Возможно, вы захотите попробовать уже существующий Mongoose C ++, который позволяет оригинальному проекту Mongoose лучше работать с C ++: https://github.com/Gregwar/mongoose-cpp

2

Другие решения

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

Хранение экземпляра вашего класса в server_param атрибут mg_server позволит вернуть его в статическую заглушку и переслать в этот экземпляр.

Это может быть достигнуто так:

class Server
{
public:
void start() {
mg_create_server(this, ev_handlerStub);
}
static int ev_handlerStub(struct mg_connection *conn, enum mg_event ev) {
((Server*)conn->server_param)->ev_handler(conn, ev);
}
int ev_handler(struct mg_connection *conn, enum mg_event ev) {
// job to do with the class instance
}
};

Действуя так, разрешите доступ к экземпляру класса внутри ev_handler метод.

2

По вопросам рекламы [email protected]