Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::bind for C function
From: Lars Viklund (zao_at_[hidden])
Date: 2012-12-20 20:32:46


On Fri, Dec 21, 2012 at 12:30:20AM +0100, Philipp Kraus wrote:
> Hello,
>
> I have got a a C library function call, which defines a function:
> typedef int (*CFunction) (State* K);
>
> So I would like to use boost::bind / boost::function to create the binding
> to a class method:
>
> boost::function<CFunction>( boost::bind(&MyClass::myMethod, this) )
>
> so that I can use the class method with the CFunction signature.
> I would like to call a class method with the object context like a
> C function.
>
> Can anybody help me to create a correct binding?

Within the standard language, no, there is no way to get a free function
pointer to an arbitrary callable.

The result of a bind expression is not a free function pointer nor
convertible to one. It's an object of an unspecified class type with a
suitable operator ().

You have several horrible choices for getting a free function pointer
from something like this.

Stateless C++11 lambdas can be coerced into a free function pointer, but
as they're stateless, they will not fly here.

The common within-the-language solution is to make a free "trampoline"
function that forwards calls to your object, which it retrieves from
some secret hiding place. In some APIs, you can pass in a "context" or
"state" object at the same place you provide the free function pointer
to the callback:

  R trampoline(State* s, A0 a0, A1 a1) {
    return get_my_callable(s)(a0, a1);
  }

  register_callback_with_api(&trampoline, &my_callable);

Another choice that is not within the standard is to generate machine
code for a trampoline-like function that directly forwards your call,
either through some code generation library like Xbyak or by taking a
suitable function, copying the generated code and patch the parts where
the call happens.

The above is often called "thunking".

In summary, the ways in order of unhorribleness are:

1) squirrel the actual callable away in some context/state provided to
the trampoline;

2) squirrel the actual callable away in some global or static variable,
which the trampoline uses;

3) dive into the abyss of code/thunk generation.

-- 
Lars Viklund | zao_at_[hidden]

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net