0

我试图在 C++ 类中包装我使用猫鼬(一个 C 库)编写的服务器。问题是我试图将函数传递ev_handlermg_create_server()在 mongoose 中创建服务器实例的 . 但它给出了一个我相信的铸造错误:

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;
                }
}
4

2 回答 2

2

回调需要是静态的,然后您应该使用静态存根重定向到类实例。

将类的实例存储在server_param属性 ofmg_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方法内的类实例。

于 2014-12-02T19:41:03.937 回答
2

您的问题是您将 C++ 成员函数传递给需要自由函数指针的参数。

Mongoose 是一个 C API,它的所有回调参数都是 C 风格的函数,在 C++ 中是自由(非成员)函数。

成员函数指针与自由函数指针的不同之处在于,它需要this或调用方法的对象才能被调用。

在您的情况下,您正在Server类上传递一个成员函数指针。

在与哪些 C API 交互时,通常会传递一个void*上下文对象,然后将其传递给回调。然后,您将指针传递给自由函数或静态类方法(它没有this,因此可以与 C API 一起使用)。调用回调时,您将上下文对象转换为正确的类型并调用成员函数以返回对象上下文。我在猫鼬中看不到任何这样的设施。也许它在那里,我只是没有找到它。

您可能想尝试已经存在的 Mongoose C++,它派生出原始的 Mongoose 项目以更好地使用 C++:https ://github.com/Gregwar/mongoose-cpp

于 2014-12-01T13:29:56.857 回答