std::bind to c-style function pointer

Let's say I have to pass a function pointer to a library, and the library will call that function with no parameters. I got the impression hat std::bind allows me to bind a parameter to the function giving me an address that I can pass to the library so that then the function is called by the library with 0 parameters, on my end it is called with the parameters I want.

Somehow I don't think this is true, but I just wanted to check - is this true?
Last edited on
AFAIK it works in reverse. You give bind some parameters to "bind" so that when you call it later those parameters are interested inserted for you.

If you want to do it the other way, couldn't you just make a wrapper function that takes no arguments and calls the other one with the args you want?
Last edited on
I can't just make arbitrary wrapper functions at runtime ;p
Er wait I think I just contradicted myself...

Yes, bind does it the way you want. You would just bind all the parameters to the function, then you can call it with no arguments. If you want different parameters, just rebind them.
Can I do this?
1
2
3
4
5
6
7
8
9
void f(char const*str)
{
    std::cout << str << std::endl;
}

//...

LibraryObj1.add(static_cast<void (*)()>(std::bind(f, "A")));
LibraryObj2.add(static_cast<void (*)()>(std::bind(f, "B")));
Or would LibraryObj1 pass "B" when calling f?

EDIT: Looks like it can't: http://ideone.com/I5bMyB

Disappointing...
Last edited on
Each invocation of bind creates a new function wrapper basically. So they would be separate, yes.
Last edited on
I can't get them to be converted to c-style function pointers, though, so it is not useful for what I want to do :(

Any alternatives?

EDIT: I guess my question is how to do the impossible - I've done some reading and I understand how to do what I want to do.
Last edited on
You could make the library take std::function objects instead of C function pointers. :P

I can't see another way around this because when you bind the function you have to store the data that is bound somewhere (part of a class or whatever), but a C pointer doesn't let you do that since it just points to some code (basically).
C style callbacks almost always take a "userdata" parameter so that problems like this can be addressed.

That is, something like this is typical:

1
2
3
4
5
6
7
8
void mycallback(void* userdata)
{
  //...
}

//...

func_that_takes_a_callback( mycallback, &foo );


Here, &foo would be passed as 'userdata' when the callback is called.


Using that, you can simply wrap the functor in a C-style callback function and use the userdata value to hold the functor object:

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef std::function<void()> callback_t;

void c_callback_wrapper( void* userdata )
{
  auto& callback = *reinterpret_cast<callback_t*>(userdata);
  callback();
}

//...

callback_t foo = std::bind( ... );

func_that_takes_a_callback( c_callback_wrapper, &foo );


A problem with this approach (and C style callbacks in general), is that the callback functor (in this case foo) must not go out of scope or be destroyed while there is still possibility of it being called.
Last edited on
@Disch yes I know and am aware of that, however there are situations where the library was poorly designed. Still though, it will help people who find this thread via google.
I have yet to see a respectable/usable library that does not offer a userdata pointer for its callbacks. I would be very curious to know what lib you're using that doesn't have that functionality.
Actually my problem wasn't with a library that didn't have a way to give custom user data - I was just trying to see if I could take some arbitrary std::function and get a c-style function pointer from it. I was wanting to do some magic where I used member functions of a class as my callbacks, but the issue is that the way the this pointer gets passed is implementation defined and I didn't want to relay on that. I've settled on forwarding since it works for what I need.
closed account (S6k9GNh0)
Boost Asio does not use a "user data pointer" for its callbacks. It expects you to use std::bind or handle it some other way.
@ computerquip: I said "C style" callbacks - where C++ functors are not an option.

obviously there's no need for them if you're using std::function.
Topic archived. No new replies allowed.