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