Ah, yes, good idea. I would register an instance of a wrapper with a __call__ method, that would call my Python callback.
Thanks! Paul Holger Brandsmeier wrote: > Paul, > > Oh, all of these approaches can be made to work, just not as direct as > ".def( "register_tau4ehS", register_tau4ehS)". If you at least relax > your callback mechanism a little and allow that for a callback you > both store a function pointer and an arbitrary object for the context, > void* or better a smart pointer, then you can hide instances of > classes in that mechanism nicely. And still you can use a raw function > pointer as before. > > -Holger > > On Sat, Oct 27, 2012 at 6:37 PM, Paul O. Seidon <p.osei...@datec.at> > wrote: >> 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.osei...@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@python.org >>>> http://mail.python.org/mailman/listinfo/cplusplus-sig >> >> >> _______________________________________________ >> Cplusplus-sig mailing list >> Cplusplus-sig@python.org >> http://mail.python.org/mailman/listinfo/cplusplus-sig _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig