Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::bind for C function
From: Jeremiah Willcock (jewillco_at_[hidden])
Date: 2012-12-20 20:15:41


On Fri, 21 Dec 2012, Philipp Kraus wrote:

>
> Am 21.12.2012 um 01:57 schrieb Jeremiah Willcock:
>
>> On Fri, 21 Dec 2012, Philipp Kraus wrote:
>>
>>>
>>> Am 21.12.2012 um 00:59 schrieb Jeremiah Willcock:
>>>
>>>> On Fri, 21 Dec 2012, 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?
>>>>
>>>> Assuming State* is void* or something that you can control the definition of, what about this?
>>>
>>> Sorry, I can't do this, the typedef is fixed, I must use it in exactly this case.
>>
>> Does it have certain members that some other part of the code uses?
>
> Yes, the typdef comes from a header file of a library, so all library calls uses the typedef.

Can you add some member that is a void* or such that you can use to point
to your function object? Is there one already?

>>>> extern "C"
>>>> void call_function_object(void* obj) {
>>>> (*static_cast<function_obj_type*>(obj))();
>>>> }
>>>>
>>>> where function_obj_type is something that you create that acts like the boost::bind result (or is just boost::function<void ()>). Note that you are responsible for managing the lifetime of the function object you use in this way, since you pass a non-owning pointer to it into the C code.
>>>
>>>
>>> Can I cast the boost::bind result to the typedef definition?
>>> I need something like
>>>
>>> my_c_call( static_cast<CFunction>( boost::bind(&MyClass::myMethod, this) ) )
>>
>> I don't think boost::bind result types are documented, so you would need C++11's decltype/auto to get its type. You will still need to either put the function object on the heap or make sure it is alive during the time that it might be called.
>
> Do you know a way to bind a class member function like a C function without C++11(I can not use the C++11 definition at the moment) ? The function exists during execution, because if my object is destroyed, the C bindings are also destroyed.
> My first idea is / was, that I create a boost::function object and get its function pointer and cast the pointer to my typedef definition, so that I can push the casted pointer to my C function.

It's easier than that:

extern "C" call_boost_function(void* f) {
   (*static_cast<boost::function<void ()>*>(f))();
}

If f needed to be a State* instead, you might need (f->some_member) where
some_member is the void* that you use for your part of the handler.

-- Jeremiah Willcock


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