bdesham
bdesham

Reputation: 16089

Passing an instance method to an API that expects a C function pointer

I have a C API to a data source. To be notified that new data is available you give the API a callback in the form of a function pointer; your callback will be called when data comes in. The API’s header contains lines like this:

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

void set_data_callback(DataCallback processor);

My C++ class has an instance method with the signature

void MyClass::process_data(DataRecord *data);

and in the constructor of MyClass I’d like to set the new instance’s process_data method as the data callback for the C API. Following this answer I tried to write this code in the constructor:

typedef void (MyClass::data_callback_t)(DataRecord*);
data_callback_t callback = &MyClass::process_data;
set_data_callback(callback);

When I do this I get the error

error C2664: 'set_data_callback' : cannot convert parameter 2 from 'data_callback_t' to 'DataCallback'

There is no context in which this conversion is possible

(I am using Visual C++ 2010 Express, although I hope that doesn’t make a difference.)

How can I extract a C function pointer from an instance and a method?

Upvotes: 1

Views: 81

Answers (1)

Barry
Barry

Reputation: 303337

You can't. MyClass::process_data can be thought of as a void(MyClass*, DataRecord*), which is the wrong type. You'd have to wrap your class pointer into the call somehow.

One approach might be to introduce a type with a static pointer:

struct MyClassCallbackHelper
{
    static MyClass* myClass;

    static void callback(DataRecord* record) {
        myClass->process_data(record);
    }
};

So that you can do:

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

Upvotes: 1

Related Questions