[C++-sig] [boost.python] Register a Python-callable with C++ code and call it from C++ code?

Holger Brandsmeier brandsmeier at gmx.de
Sat Oct 27 17:36:58 CEST 2012


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