[C++-sig] [boost.python] Register a Python-callable with C++ code and call it from C++ code?
Paul O. Seidon
p.oseidon at datec.at
Sat Oct 27 18:37:57 CEST 2012
I see, thank you Holger,
I did something similar at first, I did the registering and calling in a
Python wrapper. But creating an EventEmitter is rather expensive compared to
the creation of a Variable impl'ed in cpp. So I wanted to move that code to
cpp too.
BTW, SWIG does it this way too. There you have to add code wich is called
before/after the call into cpp.
Tanks
Paul
Holger Brandsmeier wrote:
> Paul,
>
> if I see this correctly, then you are trying to register a function to
> python in
> .def( "register_tau4ehS", register_tau4ehS)
> which is expecting a pointer to a function to python. You can not do
> that. Python can not pass function pointers as arguments, and so can't
> boost::python.
>
> When I want to use the callback design pattern with python, I do the
> following. A callback is for me an _object_ with has a certain member
> function, say `call`, and that expects arguments as you want them, in
> your case EventEmitterSync3<TYPE>&. When I register the class I pass a
> shared_ptr to that object. Later I can call that object.
>
> In python I make a wrapper for that class, and in python I derive from
> that class. Then in python I instantiate those derived classes and can
> pass them to the register method. (Usually I like to create a class in
> python that in the constructor takes a lambda function.)
>
> -Holger
>
> On Sat, Oct 27, 2012 at 4:12 PM, Paul O. Seidon <p.oseidon at datec.at>
> wrote:
>> I want to register Python-callables with my VariableFloat-class (which is
>> a subclass of a template-class Variable<double>) and call them if the
>> variable's value changes.
>>
>> For this I added an instance of class EventEmitter, which should hold
>> references to those callbacks. So, VariableFloat delegates to
>> EventEmitter, when it comes to deal with callbacks (reg'ing and calling).
>>
>> template <class TYPE>
>> class EventEmitterSync3
>> {
>> public:
>>
>> <snip/>
>>
>> void operator()() // Call the handler
>> {
>> if (_p_tau4eh)
>> (*_p_tau4eh)( *this);
>> };
>>
>> void register_tau4ehS( void (*callable)(
>> EventEmitterSync3<TYPE>& )) // Register the handler
>> { _p_tau4eh = callable;
>> };
>> <snip/>
>>
>> private:
>> void (*_p_tau4eh)( EventEmitterSync3<TYPE>& )
>> =
>> NULL; // The handler
>> };
>>
>>
>> The class VariableFloat (actually its base class _Variable<TYPE>) holds a
>> member of type EventEmitterSync<TYPE> like so:
>>
>> private:
>> EventEmitterSync3<TYPE> _tau4ee_on_change;
>>
>> and the wrapper definitions are
>>
>> void (VariableFloat::*register_tau4ehS)( void (*)(
>> EventEmitterSync3<double>& )) = &VariableFloat::register_tau4ehS;
>>
>> and
>>
>> .def( "register_tau4ehS", register_tau4ehS)
>>
>>
>> Compiling yields errors coming from boost being rather cryptic to me. But
>> the last few lines say:
>>
>>
/media/truecrypt13/D.X/Projects/DDG/tau4/src/cpp/src/tau4misc/main.cpp:43:1:
>> required from here
>> /usr/include/boost/python/converter/registered.hpp:86:7: error: no
>> matching function for call to ?register_shared_ptr1(void (*)
>> (EventEmitterSync3<double>&))?
>> /usr/include/boost/python/converter/registered.hpp:86:7: note: candidate
>> is: /usr/include/boost/python/converter/registered.hpp:77:3: note:
>> template<class T> void
>> boost::python::converter::detail::register_shared_ptr1(const volatile T*)
>> /usr/include/boost/python/converter/registered.hpp:77:3: note: template
>> argument deduction/substitution failed:
>> /usr/include/boost/python/converter/registered.hpp:86:7: note: types
>> ?const volatile T? and ?void(EventEmitterSync3<double>&)? have
>> incompatible cv-qualifiers
>>
>> Seems I have to put "const volatile" somewhere?
>>
>> I found some dox, which could be relevant, here:
>> http://www.boost.org/doc/libs/1_51_0/libs/python/doc/v2/callbacks.html
>>
>> But I am not sure how to apply that info to my problem. I tried to change
>> all function pointers into objects, but that didn't work.
>>
>> Has anyone some sample code on storing pointers to Python functions and
>> then calling them and is willing to share it?
>>
>> Paul
>>
>>
>>
>>
>>
>>
>> _______________________________________________
>> Cplusplus-sig mailing list
>> Cplusplus-sig at python.org
>> http://mail.python.org/mailman/listinfo/cplusplus-sig
More information about the Cplusplus-sig
mailing list