0

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

2 に答える 2

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

于 2014-12-01T13:29:56.857 に答える
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メソッド内のクラス インスタンスへのアクセスを許可します。

于 2014-12-02T19:41:03.937 に答える