I have a function in an external library that I cannot change with the following signature:
void registerResizeCallback(void (*)(int, int))
I want to pass in a member function as the callback, as my callback needs to modify instance variables.
Obviously this isn't possible with a simple:
registerResizeCallback(&Window::Resize);
so I'm not really sure how to solve the problem.
As Igor Oks indicates, you can't do this. The remainder of this question is not so much an answer to your problem, but a discussion of how something like this should work with a properly designed callback API (it appears the one you're using isn't).
Most well-designed callback interfaces let you provide a "void *
" or some other way to get a context in the callback. A common way to use this with C++ is to pass an object pointer in the void *
context parameter, then the callback function can cast it back into an object pointer and call the member method to do the real work. It's too bad the callback API you're using doesn't provide for context data.
Strictly speaking, the callback must be extern "C"
, but using static member methods for callbacks is common and I think in practice there's never a problem. (This is assuming that the callback API is a C interface, which is by far the most common).
An example:
// callback API declaration's
extern "C" {
typedef unsigned int callback_handle_t;
typedef void (*callback_fcn_t)( void* context, int data1, int data2);
callback_handle_t RegisterCallback( callback_fcn_t, void* context);
void UnregisterCallback( callback_handle_t);
}
// ----------------------------------
// prototype for wrapper function that will receive the callback and
// transform it into a method call
extern "C"
static void doWorkWrapper( void* context, int data1, int data2);
// the class that does the real work
class worker {
public:
worker() {
hCallback = RegisterCallback( doWorkWrapper, this);
}
~worker() {
UnregisterCallback( hCallback);
}
void doWork( int data1, int data2) {
// ...
};
private:
callback_handle_t hCallback;
};
// the wrapper that transforms the callback into a method call
extern "C"
static void doWorkWrapper( void* context, int data1, int data2)
{
worker* pWorker = static_cast<worker*>( context);
pWorker->doWork( data1, data2);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With