我试图在C ++类中包装我使用mongoose(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);
在mongoose中创建服务器的实例。但是我认为它会给出一个投射错误:
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;
}
}
答案 0 :(得分:2)
您的问题是您将C ++成员函数传递给需要自由函数指针的参数。
Mongoose是一个C API,它的所有回调参数都是C样式函数,在C ++中它们是免费的(非成员)函数。
成员函数指针与自由函数指针的不同之处在于它需要this
或调用该方法的对象,以便被调用。
在您的情况下,您正在Server
类传递成员函数指针。
在与哪些C API交互时,传递void*
上下文对象是常见的,然后传递给回调。然后,您将指针传递给自由函数或静态类方法(它没有this
,因此可以使用C API)。调用回调时,然后将上下文对象强制转换为正确的类型,并调用成员函数以返回到对象上下文。我无法在Mongoose看到任何这样的设施。也许它就在那里,而我却找不到它。
您可能想尝试已经存在的Mongoose C ++,它可以使原始的Mongoose项目更好地与C ++协同工作:https://github.com/Gregwar/mongoose-cpp
答案 1 :(得分: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
方法中的类实例。