want to pass boost::bind to a method expecting a plain function pointer (same signature).
typedef void TriggerProc_type(Variable*,void*);
void InitVariable(TriggerProc_type *proc);
boost::function<void (Variable*, void*)> triggerProc ...
InitVariable(triggerProc);
error C2664: 'InitVariable' : cannot convert parameter 1 from
'boost::function<Signature>' to 'void (__cdecl *)(type *,void *)'
I can avoid storing a boost::function and just pass the bound functor directly, but then I get similar error:
error C2664: 'blah(void (__cdecl *)(type *,void *))' : cannot convert parameter
1 from 'boost::_bi::bind_t<R,F,L>' to 'void (__cdecl *)(type *,void *)'
This is by design. Basically, since
bind
returns a completely different type, there's no way that this will work. Basically, a binder proxy object cannot be converted to a C function pointer (since it isn't one: it's a function object). The type returned byboost::bind
is complicated. The current C++ standard allows no good way of doing what you want. C++0x will be fitted with adecltype
expression which could be used here to achieve something like this:Notice that this might or might not work. I have no way of testing it.
Has anyone noticed that the accepted answer only works with trivial cases? The only way that function<>::target() will return an object that can be bound to a C callback, is if it was constructed with an object that can be bound to a C callback. If that's the case, then you could have bound it directly and skipped all of the function<> nonsense to begin with.
If you think about it, there isn't any magic solution to this. A C-style callback is stored as a single pointer which points to executable code. Any nontrivial boost::function<> is going to need at least two pointers: one to the executable code, the other to the data that's needed to set up the call (e.g. the 'this' pointer, in the case of a bound member function).
The right way to use boost::function and boost::bind with C callbacks is to create a shim function that satisfies the callback signature, figures out which function<> to call, and calls it. Usually C callbacks will have some kind of a void* for 'user data'; that's where you stash your function pointer:
Of course, if your callback signature doesn't include some kind of user data pointer, you're out of luck. But any callback that doesn't include a user data pointer is already unusable in most real-world scenarios, and needs to be rewritten.
I think you want to use the target() member function of boost::function (isn't that a mouthful...)
see boost mailing page [boost] [Function] Problem using target() with boost::mem_fn and boost::bind
can you get it working with bind?
update: Okay, well the intent is to bind a method into a function-callback. so now what?