C++ 将实例方法传递给需要C函数指针的API

C++ 将实例方法传递给需要C函数指针的API,c++,C++,我有一个数据源的C API。为了得到新数据可用的通知,您以函数指针的形式给API一个回调;当数据进入时,将调用您的回调。API的标题包含如下行: struct DataRecord { ... }; typedef void (*DataCallback)(DataRecord *data); void set_data_callback(DataCallback processor); 我的C++类有一个签名方法的实例方法 void MyClass::process_data(DataRe

我有一个数据源的C API。为了得到新数据可用的通知,您以函数指针的形式给API一个回调;当数据进入时,将调用您的回调。API的标题包含如下行:

struct DataRecord { ... };
typedef void (*DataCallback)(DataRecord *data);

void set_data_callback(DataCallback processor);

我的C++类有一个签名方法

的实例方法
void MyClass::process_data(DataRecord *data);
在MyClass的构造函数中,我想将新实例的
process\u data
方法设置为C API的数据回调。接下来,我尝试在构造函数中编写此代码:

typedef void (MyClass::data_callback_t)(DataRecord*);
data_callback_t callback = &MyClass::process_data;
set_data_callback(callback);
当我这样做时,我得到了错误

错误C2664:“设置数据回调”:无法将参数2从“数据回调”转换为“数据回调”

没有可以进行此转换的上下文

(我使用Visual C++ 2010 Express,虽然我希望这不会有什么区别)


如何从实例和方法中提取C函数指针?

您不能
MyClass::process_data
可以被认为是一个
void(MyClass*,DataRecord*)
,这是错误的类型。您必须以某种方式将类指针包装到调用中

一种方法可能是引入带有静态指针的类型:

struct MyClassCallbackHelper
{
    static MyClass* myClass;

    static void callback(DataRecord* record) {
        myClass->process_data(record);
    }
};
因此,您可以:

MyClassCallbackHelper::myClass = this;
set_data_callback(&MyClassCallbackHelper::callback);

简而言之,你不能。除非您准备硬编码要调用的实例,然后您可以有一个非成员,例如
void process(DataRecord*data){someInstance->process_data(data);}
。为了绕过这个限制,您需要修改API,以便在注册回调时使用
void*stuff
。这是一个非常糟糕的API,它不允许传递上下文指针。。。有一些非标准库在运行时创建蹦床,还有其他使用静态(或线程局部)变量的有缺陷的方法。--如果函数直到最后一次调用回调后才返回,那就没那么可怕了……我相信这样的回调助手可以为我的应用程序工作。谢谢