Я пытаюсь обернуть в класс 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;
}
}
Ваша проблема в том, что вы передаете функцию-член C ++ параметру, который хочет указатель на свободную функцию.
Mongoose является C API, и все его параметры обратного вызова являются функциями стиля C, которые в C ++ являются свободными (не участвующими) функциями.
Указатель на функцию-член отличается от указателя на свободную функцию тем, что ему нужен this
или объект, для которого вызывается метод, для вызова.
В вашем случае вы передаете указатель функции-члена на Server
учебный класс.
При взаимодействии с какими API C обычно передают void*
объект контекста, который затем передается обратному вызову. Затем вы передаете указатель на свободную функцию или метод статического класса (который не имеет this
и поэтому может работать с C API). Когда вызывается обратный вызов, вы затем приводите объект контекста к правильному типу и вызываете функцию-член, чтобы вернуться в контекст объекта. Я не вижу такого объекта в Мангусте. Возможно это там, и я просто не нахожу это.
Возможно, вы захотите попробовать уже существующий Mongoose C ++, который позволяет оригинальному проекту Mongoose лучше работать с C ++: https://github.com/Gregwar/mongoose-cpp
Обратный вызов должен быть статическим, тогда вы должны использовать статическую заглушку для перенаправления на экземпляр класса.
Хранение экземпляра вашего класса в 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
метод.