2017-05-02 9 views
0

私はいくつかの同様の質問を見つけましたが、解決策は私の場合に適合しませんでした。 C++のメソッドでは、そのパラメータの1つとしてコールバックをとるC apiを呼び出します。非スタティックメンバ関数をコールバックとして渡します

class A 
{ 

    herr_t methodA(some parameters) {....} 

    void methodB(some parameters) 
    { 
     .... 

     int status = CAPI(other parameters, callback, last parameter); 
    } 

}; 

CAPIのプロトタイプが

herr_t CAPI(some parameters, H5L_iterate_t op, other parameters); 

あるH5L_iterate_tが

herr_t (*H5L_iterate_t)(hid_t g_id, const char *name, 
         const H5L_info_t *info, void *op_data) 

によって定義されるmethodAはH5L_iterate_tと同じシグネチャを有しています。
methodBで 、

status = CAPI(..., **(H5L_iterate_t)std::bind(&A::methodA, this, 
       std::placeholders::_1)**, ...); 

私は "から... H5L_iterate_tに変換できません" して得たコンパイルエラー。私は、コールバックとして非静的メンバー関数を渡す正しい方法は何ですか?

ありがとうございます。ほとんどいつもこのパターンに従ってコールバックを提供

+1

メンバー・メソッドポインタと関数ポインタは互換性がありません。

あなたは、あなたのオブジェクト型へのポインタにキャストバックすることができ、あなたのC++オブジェクトのアドレスへのポインタを渡すために、このユーザーデータを使用することができます。あなたは、実際のメンバメソッドをコールし、 'op_data'を通して' this'を提供するコールバックとして与えるために、フリー関数、静的メンバーメソッド、または無国籍ラムダを書くかもしれません。 –

+0

Cコールバックについては、関数ポインタが必要だと思います。したがって、非静的メンバー関数にすることはできません。 –

+0

私は静的メンバ関数を知っています、またはプレーンなc関数がそのジョブを行うことができます。しかし、私はオブジェクトの状態を変更するコールバックが必要です。 – Wqh

答えて

2

C APIに:

extern "C" 
{ 
    typedef void(*callback_function)(void* data);  

    typedef int handle_type; 

    void do_something_with_callback(handle_type, callback_function, void *data); 
} 

do_something_with_callbackが呼び出されたときにdata引数として渡すどんなことをされてのアイデアは、callback_functionに渡されます。

struct my_object 
{ 
    void initiate() 
    { 
     // call the C interface, passing our c-style callback function with 
     // a pointer to this class as the user data 
     do_something_with_callback(handle_, &callback_launch_function, this); 
    } 

private: 
    static void callback_launch_function(void * data) { 
     // the data will always be a pointer to my_object - 
     // because that's what we passed. 
     auto self = reinterpret_cast<my_object*>(data); 
     self->handle_it(); 
    } 

    // this is our c++style callback 
    void handle_it() 
    { 

    } 

    handle_type handle_; 
}; 
+0

私はこれを試していませんが、静的ではないhandle_it()を呼び出すのは問題ですか? – Wqh

+0

@Wqh 'data'引数は実際には' my_object'へのポインタであることを前提としています(この場合、私たちはそれを保証しています)。 –

+0

@Wqh:いいえ、コードはオブジェクトへのポインタを介して 'handle_it()'を呼び出しているので、 'handle_it()'は 'this'ポインタを期待どおりに受け取ります。 –

関連する問題