I ran into a problem when using a C audio library (PortAudio built with ASIO SDK, but this isn\'t really relevant to this question; the technical details would only hinder m
Your code is oversimplified. In real world both the "library function" and the callback will have a void*
"user data" parameter. You can pass a pointer to your class instance into "user data" of the "library function" and it will be forwarded into the callback where you can use that pointer to access the object.
class CallbackImplBase {
public:
virtual void CallbackImpl() = 0;
static void CallbackToPass( void* userData )
{
static_cast<CallbackImplBase*>(userData)->CallbackImpl();
}
};
class ActualCallbackImpl : public CallbackImplBase {
void CallbackImpl() { //implemented here }
};
ActualCallbackImpl callback;
callLibraryFunction( params,
&CallbackImplBase::CallbackToPass, static_cast<CallbackImplBase*>( &callback ) );
Note the static_cast
near the last parameter of the "library function" call. You won't need it unless you have multiple inheritance, it's still there anyway.
As far as I can see, the callbacks in PortAudio, such as this one, take a void*
argument for passing user data to them. You can use this to call member functions by passing a class pointer as user data, and writing a small static or non-member function to register as the C-compatible callback. For example:
// C library function
typedef void (*c_library_callback)(void * user_data);
void c_library_start_stuff(c_library_callback, void * user_data);
// C++ class using it
class audio_thing {
public:
virtual ~audio_thing() {} // Better have one of these in an abstract class
void start_stuff() {
c_library_start_stuff(&audio_thing::static_callback, this);
}
private:
// C-compatible callback forwards to the implementation
static void static_callback(void * thing) {
static_cast<audio_thing*>(thing)->callback();
}
// Derived classes implement the callback behaviour
virtual void callback() = 0;
};