Demote boost :: function to plain function pointer

I want to pass boost :: bind to a method that expects a simple 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 saving the boost :: function and just pass the linked functor directly, but then I get a 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 *)' 
+21
c ++ boost functor
Nov 11 '08 at 22:33
source share
5 answers

Has anyone noticed that the accepted answer only works with trivial cases? The only way the <> :: target () function returns an object that can be attached to a C callback is if it was constructed with an object that can be associated with a C callback. If so, then you could bind it directly and skip the whole function <> nonsense to begin with.

If you think about it, there is no magic solution. The C-style callback is stored as a single pointer that points to executable code. Any non-trivial boost :: function <> will require at least two pointers: one for the executable code, the other for the data needed to configure the call (for example, the 'this' pointer, in the case of a related member function).

The proper way to use boost :: function and boost :: bind with C callbacks is to create a pad function that satisfies the callback signature, determines which function <> to call, and calls it. Typically, C callbacks will have some kind of void * for "user data"; that when you click on a function pointer:

 typedef void (*CallbackType)(int x, void* user_data); void RegisterCallback(CallbackType cb, void* user_data); void MyCallback(int x, void* userData) { boost::function<void(int)> pfn = static_cast<boost::function<void(int)> >(userData); pfn(x); } boost::function<void(int)> fn = boost::bind(myFunction(5)); RegisterCallback(MyCallback, &fn); 

Of course, if your callback signature does not include some sort of user data pointer, you're out of luck. But any callback that does not include a user data pointer is already unsuitable for most real-world scenarios and needs to be rewritten.

+39
Aug 10 '10 at 21:32
source share
β€” -

I think you want to use the target () member function of boost :: function (right ...)

 #include <boost/function.hpp> #include <iostream> int f(int x) { return x + x; } typedef int (*pointer_to_func)(int); int main() { boost::function<int(int x)> g(f); if(*g.target<pointer_to_func>() == f) { std::cout << "g contains f" << std::endl; } else { std::cout << "g does not contain f" << std::endl; } return 0; } 
+11
Nov 11 '08 at 23:01
source share

Can you make it work with communication?

 cb_t cb = *g.target<cb_t>(); //target returns null 

This is by design . Basically, since bind returns a completely different type, there is no way this will work. In principle, a binding object cannot be converted to a C function pointer (since it is not one: it is a function object). The type returned by boost::bind is complex. The current C ++ standard does not allow you to do what you want. C ++ 0x will have a decltype expression that can be used here to achieve something like this:

 typedef decltype(bind(f, 3)) bind_t; bind_t target = *g.target<bind_t>(); 

Please note that this may or may not work. I have no way to check it.

+3
Feb 04 '09 at 16:56
source share
+2
Feb 27 '09 at 3:21
source share

Can you make it work with communication?

 #include <boost/function.hpp> #include <boost/bind.hpp> void f(int x) { (void) x; _asm int 3; } typedef void (*cb_t)(int); int main() { boost::function<void (int x)> g = boost::bind(f, 3); cb_t cb = *g.target<cb_t>(); //target returns null cb(1); return 0; } 

update: It’s good that the goal is to associate the method with a callback function. so now?

0
Feb 04 '09 at 16:45
source share



All Articles