I have a C library function with the following signature,
void register_callback(void (*callback)(int, void*), void* args);
What is the best way to get this to work with, if I have a callback of the form,
std::function<void(int)>?
I have a C library function with the following signature,
void register_callback(void (*callback)(int, void*), void* args);
What is the best way to get this to work with, if I have a callback of the form,
std::function<void(int)>?
std::function<void(int)> bob;
register_callback( [](int x, void* pbob){
auto& bob = *static_cast<std::function<void(int)>*>(pbob);
bob(x);
}, &bob );
this remains valid for as long as the variable bob
does.
A copy of bob
is not enough, the actual instance of bob
that we took a pointer to in the register_callback
call has to live long enough.
If this is difficult, consider a smart pointer wrapping said std::function
and doing a pointer to the stored std::function
.
There will be modest overhead in the above, in that we dispatch over a function pointer, then over the equivalent of a vtable, then inside the std::function
again.
What is going on above is that I make a stateless lambda to convert the void* args
into a pointer-to-std::function
, and invoke that std::function
with the int
. Stateless lambdas can convert to function pointers implicitly.
With:
class CallBack
{
public:
explicit CallBack(std::function<void(int)> f) : f(f) {}
static void to_c_api(int a, void* that)
{
reinterpret_cast<CallBack*>(that)->f(a);
}
private:
std::function<void(int)> f;
};
You may then do
CallBack callback; // should live longer than the calls
void register_callback(CallBack::to_c_api, &callback);