|
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