I want to pass a member function as a call-back. The call back is a basic function pointer.
So I have something like:
h file:
void (*pRequestFunc) (int someint) = 0;
void RegisterRequestCallBack(void (*requestFunc) (int someint))
{
pRequestFunc = requestFunc;
}
class A
{
void callBack(int someint);
}
Cpp File:
RegisterRequestCallBack(&A::callBack); // This does not work.
Note I have tried to extract this example from my larger example and cut out all the other stuff - so it might not be perfect.
The problem, as far as I understand, is that member function pointers really (under the hood) have an extra parameter (and instance - i.e. this) and are not compatible with normal function pointers.
the RegisterRequestCallBack() is in reality not my code - and so I can't change that.
So I read that boost::bind can do what I need - and I am hoping c++11 std::bind can do the same - but I could not figure out how to use it to effectively get a standard function pointer from a member function pointer...
I was going for something like:
std::bind(&A::callBack) ... that is about as far as I got, my understanding of the examples online is poor :(
NathanOliver's comment is correct, and your suspicion is mostly correct. Exactly how pointers to member functions work is not specified, but including this as a hidden argument mostly works. You just need a bit of extra work for inheritance and pointers to virtual functions (yes, you can take their address too).
Now, often callbacks include a void* parameter under your control, which you can use to pass a A*. In those cases, you can write a wrapper (static) function that casts the void* back to A* and does the actual call to &A::callback.
That's not the case here. Registration takes a single function, without data. To get this to work in real-life situations, you have to resort to drastic solutions - not portable C++. One such method is to dynamically generate assembly (!). You create - at runtime - the compiled equivalent of
void __trampoline_0x018810000 (int i)
{
A* __this = reinterpret_cast<A*>(0x018810000);
__this->callback(i);
}
As you can see, you have to generate one trampoline for every A* value, and managing lifetimes of these is a major pain.
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