C++ 将非静态成员函数作为回调传递

C++ 将非静态成员函数作为回调传递,c++,c++11,callback,C++,C++11,Callback,我发现了几个类似的问题,但解决方案不适合我的情况。 在C++方法中,我调用一个C API,它将回调作为参数之一。 class A { herr_t methodA(some parameters) {....} void methodB(some parameters) { .... int status = CAPI(other parameters, callback, last parameter); } }; CAPI的原型

我发现了几个类似的问题,但解决方案不适合我的情况。 在C++方法中,我调用一个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\u iterate\u t具有相同的签名。
在方法B中

status = CAPI(..., **(H5L_iterate_t )std::bind(&A::methodA, this,
              std::placeholders::_1)**, ...);
我得到的编译错误是“无法从…转换为H5L\u iterate\t”。我想知道以回调的形式传递非静态成员函数的正确方法是什么


提前谢谢

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\u something\u with\u callback
时,作为
data
参数传递的任何内容都将传递给
callback\u函数

您可以使用这个用户数据传递一个指向C++对象地址的指针,然后您可以将其转换回指向对象类型的指针:

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_;
};
struct my\u对象
{
void initiate()
{
//调用C接口,用
//指向此类作为用户数据的指针
使用回调函数(handle、callback、launch、this)做某事;
}
私人:
静态无效回调函数(无效*数据){
//数据将始终是指向my_对象的指针-
//因为这就是我们经过的。
自动自检=重新解释铸件(数据);
self->handle_it();
}
//这是我们的c++风格回调
void handle_it()
{
}
手柄类型手柄;
};

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\u something\u with\u callback
时,作为
data
参数传递的任何内容都将传递给
callback\u函数

您可以使用这个用户数据传递一个指向C++对象地址的指针,然后您可以将其转换回指向对象类型的指针:

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_;
};
struct my\u对象
{
void initiate()
{
//调用C接口,用
//指向此类作为用户数据的指针
使用回调函数(handle、callback、launch、this)做某事;
}
私人:
静态无效回调函数(无效*数据){
//数据将始终是指向my_对象的指针-
//因为这就是我们经过的。
自动自检=重新解释铸件(数据);
self->handle_it();
}
//这是我们的c++风格回调
void handle_it()
{
}
手柄类型手柄;
};

成员方法指针和函数指针不兼容。您可以尝试编写一个自由函数,s静态成员方法或s无状态lambda作为回调函数,该回调函数调用实际成员方法,并通过
op_data
提供
this
。对于C回调函数,我相信您需要一个函数指针。所以它不可能是非静态成员函数,我知道静态成员函数或普通c函数可以完成这项工作。但是我需要回调来更改对象的状态。成员方法指针和函数指针不兼容。您可以尝试编写一个自由函数,s静态成员方法或s无状态lambda作为回调函数,该回调函数调用实际成员方法,并通过
op_data
提供
this
。对于C回调函数,我相信您需要一个函数指针。所以它不可能是非静态成员函数,我知道静态成员函数或普通c函数可以完成这项工作。但是我需要回调来更改对象的状态。我还没有尝试过,但是从静态函数调用非静态句柄_it()是否有问题?@Wqh,前提是
数据
参数实际上是指向
我的对象
的指针(在本例中,我们确保它是)那么这是完全合法和正确的。@Wqh:不,这不是问题,因为代码通过指向对象的指针调用
handle\u it()。但是我在回调函数中添加了void do_something_with_callback(句柄类型,回调函数,void*数据){printf(“in do something with callback”);callback_函数()}和其他printf。我没有看到回调函数输出的文本。在gdb中,我没有看到回调被调用。非常奇怪。我想我需要将数据传递给回调,但是回调仍然不起作用。void do_something_with_callback(handle_type,callback_函数,void data){printf(“in do something with callback\n”);callback_函数((void)data)}我没有尝试过这个,但是调用非静态句柄_it()有问题吗从静态函数?@Wqh假设
数据
参数确实是指向
我的对象
(在本例中,我们已经确保它是)的指针,那么这是完全合法和正确的。@Wqh:不,这不是问题,因为代码通过指向对象的指针调用
句柄(
),所以
句柄()
按预期接收一个
指针。您是对的,这不是问题,我喜欢此解决方案。但是我在回调函数中添加了void do_something_with_callback(句柄类型,回调函数,void*数据){printf(“in do something with callback”);callback_函数()}和其他printf。我没有看到回调函数输出的文本。在gdb中,我没有看到回调被调用。非常奇怪。我想我需要将数据传递给回调,但是回调仍然不起作用。void do_something_with_callback(句柄类型、回调函数、void数据){printf(“in do something with callback”);callback_函数((void)data);}