Thread: [pygccxml-development] Parameter passing, ownership semantics
Brought to you by:
mbaas,
roman_yakovenko
From: Gustavo C. <gjc...@gm...> - 2007-02-18 15:09:26
|
Take this program, where Simulator and EventImpl are C++ classes wrapped by Py++ / boost python: class MyEvent(EventImpl): def Notify(self, *args): print "Notify!", args ev = MyEvent() t1 = Seconds(1) Simulator.Schedule(t1, ev) Simulator.Run() There's a memory error here because 'ev' is passed into Simulator, which takes ownership of the value and eventually calls delete on C++ counterpart to 'ev'. valgrind says that Address 0xsomething is 8 bytes inside the object allocated by boost python. If, OTOH, I do "Simulator.Schedule(Seconds(1), MyEvent())", then the python objects are prematurely destroyed, and another memory error occurs. I notice that Py++ "call policies" are always related to the return value; I don't see how to customize the parameter passing aspect of it all. Any advice is appreciated. Thanks in advance. -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Roman Y. <rom...@gm...> - 2007-02-18 17:36:48
|
On 2/18/07, Gustavo Carneiro <gjc...@gm...> wrote: > Take this program, where Simulator and EventImpl are C++ classes wrapped > by Py++ / boost python: > > class MyEvent(EventImpl): > > def Notify(self, *args): > print "Notify!", args > > > ev = MyEvent() > t1 = Seconds(1) > Simulator.Schedule(t1, ev) > Simulator.Run() > > There's a memory error here because 'ev' is passed into Simulator, which > takes ownership of the value and eventually calls delete on C++ counterpart > to 'ev'. valgrind says that Address 0xsomething is 8 bytes inside the > object allocated by boost python. > > If, OTOH, I do "Simulator.Schedule(Seconds(1), MyEvent())", then the > python objects are prematurely destroyed, and another memory error occurs . > > I notice that Py++ "call policies" are always related to the return value; > I don't see how to customize the parameter passing aspect of it all. > > Any advice is appreciated. Thanks in advance. I don't fully understand your situation. Take a look on this FAQ( http://boost.org/libs/python/doc/v2/faq.html#ownership ) Does it help? If not, please describe your situation with some C++ code. If it do help, than you can use "function transformation" feature to create the wrapper. ( http://language-binding.net/pyplusplus/documentation/functions/transformation/built_in/built_in.html ) Thanks. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2007-02-18 18:20:56
|
On 2/18/07, Roman Yakovenko <rom...@gm...> wrote: > > On 2/18/07, Gustavo Carneiro <gjc...@gm...> wrote: > > Take this program, where Simulator and EventImpl are C++ classes > wrapped > > by Py++ / boost python: > > > > class MyEvent(EventImpl): > > > > def Notify(self, *args): > > print "Notify!", args > > > > > > ev = MyEvent() > > t1 = Seconds(1) > > Simulator.Schedule(t1, ev) > > Simulator.Run() > > > > There's a memory error here because 'ev' is passed into Simulator, > which > > takes ownership of the value and eventually calls delete on C++ > counterpart > > to 'ev'. valgrind says that Address 0xsomething is 8 bytes inside the > > object allocated by boost python. > > > > If, OTOH, I do "Simulator.Schedule(Seconds(1), MyEvent())", then the > > python objects are prematurely destroyed, and another memory error > occurs . > > > > I notice that Py++ "call policies" are always related to the return > value; > > I don't see how to customize the parameter passing aspect of it all. > > > > Any advice is appreciated. Thanks in advance. > > I don't fully understand your situation. Take a look on this FAQ( > http://boost.org/libs/python/doc/v2/faq.html#ownership ) > > Does it help? Yes, it seems to match my problem. Now, trying to implement the advice I stumble upon the "Make sure the C++ object is held by auto_ptr" part, which I have no idea how to do. How do I tell Py++ to do that? If not, please describe your situation with some C++ code. > > If it do help, than you can use "function transformation" feature to > create the wrapper. > > ( > http://language-binding.net/pyplusplus/documentation/functions/transformation/built_in/built_in.html > ) That doesn't seem to help; I don't know enough of Py++ internals to be able to my own function transformation in useful time. -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Roman Y. <rom...@gm...> - 2007-02-18 18:24:37
|
On 2/18/07, Gustavo Carneiro <gjc...@gm...> wrote: > > I don't fully understand your situation. Take a look on this FAQ( > > http://boost.org/libs/python/doc/v2/faq.html#ownership ) > > > > Does it help? > > Yes, it seems to match my problem. You have function that takes ownership on a pointer, right? > Now, trying to implement the advice I stumble upon the "Make sure the C++ > object is held by auto_ptr" part, which I have no idea how to do. How do I > tell Py++ to do that? > > If not, please describe your situation with some C++ code. > > > > If it do help, than you can use "function transformation" feature to > > create the wrapper. > > > > ( > http://language-binding.net/pyplusplus/documentation/functions/transformation/built_in/built_in.html > > ) > > That doesn't seem to help; I don't know enough of Py++ internals to be > able to my own function transformation in useful time. Not a problem, I need this too, I will create it for you and will let you know ( +- 1 hour ) -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Roman Y. <rom...@gm...> - 2007-02-18 19:04:18
|
I committed new function transformation: transfer ownership. The documentation will come later. For usage example take a look on unittests: ( look for "transfer_ownership" ) http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/function_transformations_tester.py?view=markup http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/function_transformations_to_be_exported.hpp?view=markup -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2007-02-18 19:50:14
|
On 2/18/07, Roman Yakovenko <rom...@gm...> wrote: > > I committed new function transformation: transfer ownership. The > documentation > will come later. For usage example take a look on unittests: > ( look for "transfer_ownership" ) > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/function_transformations_tester.py?view=markup > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/function_transformations_to_be_exported.hpp?view=markup Thanks! Unfortunately the generated code does not compile when I try to use that feature: default/bindings/python/__call_policies.pypp.hpp:14:58: error: boost/python/suite/indexing/iterator_range.hpp: No such file or directory default/bindings/python/__call_policies.pypp.hpp:172: error: 'pyplusplus::call_policies::bpl::indexing' has not been declared default/bindings/python/__call_policies.pypp.hpp:172: error: ISO C++ forbids declaration of 'iterator_range' with no type default/bindings/python/__call_policies.pypp.hpp:172: error: typedef name may not be a nested-name-specifier default/bindings/python/__call_policies.pypp.hpp:172: error: expected ';' before '<' token [...etc...] From "boost/python/suite/indexing/iterator_range.hpp: No such file or directory", does this sound like I need to get a newer boost::python library or something? Thanks in advance. -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Roman Y. <rom...@gm...> - 2007-02-18 19:56:37
|
On 2/18/07, Gustavo Carneiro <gjc...@gm...> wrote: > On 2/18/07, Roman Yakovenko <rom...@gm...> wrote: > > I committed new function transformation: transfer ownership. The > documentation > > will come later. For usage example take a look on unittests: > > ( look for "transfer_ownership" ) > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/function_transformations_tester.py?view=markup > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/function_transformations_to_be_exported.hpp?view=markup > > Thanks! > > Unfortunately the generated code does not compile when I try to use that > feature: > > default/bindings/python/__call_policies.pypp.hpp:14:58: > error: boost/python/suite/indexing/iterator_range.hpp: No > such file or directory > default/bindings/python/__call_policies.pypp.hpp:172: > error: 'pyplusplus::call_policies::bpl::indexing' has not > been declared > default/bindings/python/__call_policies.pypp.hpp:172: > error: ISO C++ forbids declaration of 'iterator_range' with no type > default/bindings/python/__call_policies.pypp.hpp:172: > error: typedef name may not be a nested-name-specifier > default/bindings/python/__call_policies.pypp.hpp:172: > error: expected ';' before '<' token > [...etc...] > > From "boost/python/suite/indexing/iterator_range.hpp: No > such file or directory", does this sound like I need to get a newer > boost::python library or something? Something like that. Boost.Python, out of the box, comes with little support to STL containers. To make the long story short you have to install new indexing suite that comes with Py++: ( http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/indexing_suite_v2/ ) Here you will find more information about new indexing suite http://language-binding.net/pyplusplus/documentation/containers.html. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2007-02-18 22:20:49
|
On 2/18/07, Roman Yakovenko <rom...@gm...> wrote: > > On 2/18/07, Gustavo Carneiro <gjc...@gm...> wrote: > > On 2/18/07, Roman Yakovenko <rom...@gm...> wrote: > > > I committed new function transformation: transfer ownership. The > > documentation > > > will come later. For usage example take a look on unittests: > > > ( look for "transfer_ownership" ) > > > > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/function_transformations_tester.py?view=markup > > > > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/function_transformations_to_be_exported.hpp?view=markup > > > > Thanks! > > > > Unfortunately the generated code does not compile when I try to use > that > > feature: > > > > default/bindings/python/__call_policies.pypp.hpp:14:58: > > error: boost/python/suite/indexing/iterator_range.hpp: No > > such file or directory > > default/bindings/python/__call_policies.pypp.hpp:172: > > error: 'pyplusplus::call_policies::bpl::indexing' has not > > been declared > > default/bindings/python/__call_policies.pypp.hpp:172: > > error: ISO C++ forbids declaration of 'iterator_range' with no type > > default/bindings/python/__call_policies.pypp.hpp:172: > > error: typedef name may not be a nested-name-specifier > > default/bindings/python/__call_policies.pypp.hpp:172: > > error: expected ';' before '<' token > > [...etc...] > > > > From "boost/python/suite/indexing/iterator_range.hpp: No > > such file or directory", does this sound like I need to get a newer > > boost::python library or something? > > Something like that. Boost.Python, out of the box, comes with little > support > to STL containers. To make the long story short you have to install new > indexing > suite that comes with Py++: > ( > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/indexing_suite_v2/ > ) > > Here you will find more information about new indexing suite > http://language-binding.net/pyplusplus/documentation/containers.html. Thanks. After much effort to rebuilt a patched boost library, it now compiles fine. However, the methods that are affected by the transformation (Schedule*) are receiving some kind of name mangling: >>> dir(ns3.Simulator) ['Now', 'Run', 'ScheduleDestroy_126390ccfc1f22f22289536ea47d3ecb', 'ScheduleNow_3692da707df52052648f9d5435d958c4', 'Schedule_fbf096d706be19b392c1e3fbcd3bf544', 'Stop', '__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__'] Bug? -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Roman Y. <rom...@gm...> - 2007-02-19 05:28:29
|
On 2/19/07, Gustavo Carneiro <gjc...@gm...> wrote: > After much effort to rebuilt a patched boost library, it now compiles > fine. However, the methods that are affected by the transformation > (Schedule*) are receiving some kind of name mangling: > > >>> dir(ns3.Simulator) > ['Now', 'Run', > 'ScheduleDestroy_126390ccfc1f22f22289536ea47d3ecb', > 'ScheduleNow_3692da707df52052648f9d5435d958c4', > 'Schedule_fbf096d706be19b392c1e3fbcd3bf544', 'Stop', > '__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', > '__hash__', '__init__', '__module__', '__new__', '__reduce__', > '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__'] > > Bug? No, feature: file:///home/roman/language-binding/production/www/pyplusplus/documentation/functions/transformation/name_mangling.html You can use "alias" property to change it: Simulator = mb.class_( 'Simulator' ) Simulator.mem_fun( 'ScheduleDestroy' ).alias = .... -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2007-02-18 22:48:33
|
On 2/18/07, Gustavo Carneiro <gjc...@gm...> wrote: > > On 2/18/07, Roman Yakovenko <rom...@gm...> wrote: > > > On 2/18/07, Gustavo Carneiro <gjc...@gm...> wrote: > > > On 2/18/07, Roman Yakovenko <rom...@gm...> wrote: > > > > I committed new function transformation: transfer ownership. The > > > documentation > > > > will come later. For usage example take a look on unittests: > > > > ( look for "transfer_ownership" ) > > > > > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/function_transformations_tester.py?view=markup > > > > > > > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/function_transformations_to_be_exported.hpp?view=markup > > > > > > > > Thanks! > > > > > > Unfortunately the generated code does not compile when I try to use > > that > > > feature: > > > > > > default/bindings/python/__call_policies.pypp.hpp:14:58: > > > error: boost/python/suite/indexing/iterator_range.hpp: No > > > such file or directory > > > default/bindings/python/__call_policies.pypp.hpp:172: > > > error: 'pyplusplus::call_policies::bpl::indexing' has not > > > been declared > > > default/bindings/python/__call_policies.pypp.hpp:172: > > > error: ISO C++ forbids declaration of 'iterator_range' with no type > > > default/bindings/python/__call_policies.pypp.hpp:172: > > > error: typedef name may not be a nested-name-specifier > > > default/bindings/python/__call_policies.pypp.hpp:172: > > > error: expected ';' before '<' token > > > [...etc...] > > > > > > From "boost/python/suite/indexing/iterator_range.hpp: No > > > such file or directory", does this sound like I need to get a newer > > > boost::python library or something? > > > > Something like that. Boost.Python, out of the box, comes with little > > support > > to STL containers. To make the long story short you have to install new > > indexing > > suite that comes with Py++: > > ( > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/indexing_suite_v2/ > > ) > > > > Here you will find more information about new indexing suite > > http://language-binding.net/pyplusplus/documentation/containers.html. > > > > Thanks. > > After much effort to rebuilt a patched boost library, it now compiles > fine. However, the methods that are affected by the transformation > (Schedule*) are receiving some kind of name mangling: > > >>> dir(ns3.Simulator) > ['Now', 'Run', 'ScheduleDestroy_126390ccfc1f22f22289536ea47d3ecb', > 'ScheduleNow_3692da707df52052648f9d5435d958c4', > 'Schedule_fbf096d706be19b392c1e3fbcd3bf544', 'Stop', '__class__', > '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', > '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', > '__repr__', '__setattr__', '__str__', '__weakref__'] > Even with the name mangling problem, something was not right: gjc@nazgul:python$ python test-schedule.py Traceback (most recent call last): File "test-schedule.py", line 11, in <module> Simulator.Schedule_fbf096d706be19b392c1e3fbcd3bf544(t1, ev) Boost.Python.ArgumentError: Python argument types in Simulator.Schedule_fbf096d706be19b392c1e3fbcd3bf544(Time, MyEvent) did not match C++ signature: Schedule_fbf096d706be19b392c1e3fbcd3bf544(ns3::Time time, std::auto_ptr<ns3::EventImpl> event) Then I saw something I missed in the unit test, and added this code: EventImpl = mb.class_('EventImpl') EventImpl.held_type = 'std::auto_ptr< %s >' % EventImpl.decl_string (EventImpl is the type of the argument that is subject to the ownership transfer) But with the above changes the code doesn't compile (errors below). The generated source contains: bp::class_< EventImpl_wrapper, std::auto_ptr< ::ns3::EventImpl >, boost::noncopyable >( "EventImpl" ) .def( bp::init< >() ) The error comes from the ".def( bp::init< >() )" line. Manually removing the "std::auto_ptr< ::ns3::EventImpl >" part from the first line solves the compilation error. Any hints? /usr/include/boost/python/object/pointer_holder.hpp: In constructor 'boost::python::objects::pointer_holder<Pointer, Value>::pointer_holder(PyObject*) [with Pointer = std::auto_ptr<ns3::EventImpl>, Value = ns3::EventImpl]': /usr/include/boost/python/object/make_holder.hpp:83: instantiated from 'static void boost::python::objects::make_holder<0>::apply<Holder, ArgList>::execute(PyObject*) [with Holder = boost::python::objects::pointer_holder<std::auto_ptr<ns3::EventImpl>, ns3::EventImpl>, ArgList = boost::mpl::vector0<mpl_::na>]' /usr/include/boost/python/detail/make_keyword_range_fn.hpp:64: instantiated from 'boost::python::api::object boost::python::detail::make_keyword_range_constructor(const CallPolicies&, const boost::python::detail::keyword_range&, Holder*, ArgList*, Arity*) [with ArgList = boost::mpl::vector0<mpl_::na>, Arity = boost::mpl::size<boost::mpl::vector0<mpl_::na> >, Holder = boost::python::objects::pointer_holder<std::auto_ptr<ns3::EventImpl>, ns3::EventImpl>, CallPolicies = boost::python::default_call_policies]' /usr/include/boost/python/init.hpp:330: instantiated from 'void boost::python::detail::def_init_aux(ClassT&, const Signature&, NArgs, const CallPoliciesT&, const char*, const boost::python::detail::keyword_range&) [with ClassT = boost::python::class_<EventImpl_wrapper, std::auto_ptr<ns3::EventImpl>, boost::noncopyable_::noncopyable, boost::python::detail::not_specified>, CallPoliciesT = boost::python::default_call_policies, Signature = boost::mpl::vector0<mpl_::na>, NArgs = boost::mpl::size<boost::mpl::vector0<mpl_::na> >]' /usr/include/boost/python/init.hpp:399: instantiated from 'static void boost::python::detail::define_class_init_helper<0>::apply(ClassT&, const CallPoliciesT&, const Signature&, NArgs, const char*, const boost::python::detail::keyword_range&) [with ClassT = boost::python::class_<EventImpl_wrapper, std::auto_ptr<ns3::EventImpl>, boost::noncopyable_::noncopyable, boost::python::detail::not_specified>, CallPoliciesT = boost::python::default_call_policies, Signature = boost::mpl::vector0<mpl_::na>, NArgs = boost::mpl::size<boost::mpl::vector0<mpl_::na> >]' /usr/include/boost/python/init.hpp:171: instantiated from 'void boost::python::init_base<DerivedT>::visit(classT&) const [with classT = boost::python::class_<EventImpl_wrapper, std::auto_ptr<ns3::EventImpl>, boost::noncopyable_::noncopyable, boost::python::detail::not_specified>, DerivedT = boost::python::init<mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_>]' /usr/include/boost/python/def_visitor.hpp:31: instantiated from 'static void boost::python::def_visitor_access::visit(const V&, classT&) [with V = boost::python::def_visitor<boost::python::init<mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_> >, classT = boost::python::class_<EventImpl_wrapper, std::auto_ptr<ns3::EventImpl>, boost::noncopyable_::noncopyable, boost::python::detail::not_specified>]' /usr/include/boost/python/def_visitor.hpp:67: instantiated from 'void boost::python::def_visitor<DerivedVisitor>::visit(classT&) const [with classT = boost::python::class_<EventImpl_wrapper, std::auto_ptr<ns3::EventImpl>, boost::noncopyable_::noncopyable, boost::python::detail::not_specified>, DerivedVisitor = boost::python::init<mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_>]' /usr/include/boost/python/class.hpp:225: instantiated from 'boost::python::class_<T, X1, X2, X3>& boost::python::class_<T, X1, X2, X3>::def(const boost::python::def_visitor<Derived>&) [with Derived = boost::python::init<mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_>, W = EventImpl_wrapper, X1 = std::auto_ptr<ns3::EventImpl>, X2 = boost::noncopyable_::noncopyable, X3 = boost::python::detail::not_specified]' default/bindings/python/ns3.cpp:76: instantiated from here /usr/include/boost/python/object/pointer_holder.hpp:179: error: cannot allocate an object of abstract type 'ns3::EventImpl' ./default/ns3/event-impl.h:28: note: because the following virtual functions are pure within 'ns3::EventImpl': ./default/ns3/event-impl.h:31: note: virtual ns3::EventImpl::~EventImpl() ./default/ns3/event-impl.h:36: note: virtual void ns3::EventImpl::Notify() -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Roman Y. <rom...@gm...> - 2007-02-19 05:42:00
|
On 2/19/07, Gustavo Carneiro <gjc...@gm...> wrote: > Even with the name mangling problem, something was not right: > > gjc@nazgul:python$ python test-schedule.py > Traceback (most recent call last): > File "test-schedule.py ", line 11, in <module> > Simulator.Schedule_fbf096d706be19b392c1e3fbcd3bf544(t1, > ev) > Boost.Python.ArgumentError: Python argument types in > > Simulator.Schedule_fbf096d706be19b392c1e3fbcd3bf544(Time, > MyEvent) > did not match C++ signature: > Schedule_fbf096d706be19b392c1e3fbcd3bf544(ns3::Time > time, std::auto_ptr<ns3::EventImpl> event) > > Then I saw something I missed in the unit test, and added this code: > > EventImpl = mb.class_('EventImpl') > EventImpl.held_type = 'std::auto_ptr< %s >' % EventImpl.decl_string > > (EventImpl is the type of the argument that is subject to the ownership > transfer) > > But with the above changes the code doesn't compile (errors below). The > generated source contains: > > bp::class_< EventImpl_wrapper, std::auto_ptr< ::ns3::EventImpl >, > boost::noncopyable >( "EventImpl" ) > .def( bp::init< >() ) > > The error comes from the ".def( bp::init< >() )" line. Manually removing > the "std::auto_ptr< ::ns3::EventImpl >" part from the first line solves the > compilation error. > > Any hints? Yes: 1. change "std::auto_ptr< ::ns3::EventImpl >" to "std::auto_ptr< EventImpl_wrapper >" and add next line to your code: ei = mb.class_( 'EventImpl' ) ei.add_registration_code( "boost::python::implicitly_convertible< std::auto_ptr< EventImpl_wrapper >, std::auto_ptr< ::ns3::EventImpl > >();" , False ) This should help. 2. If not, please create small standalone test case, which reproduce the problem. I will take a look on it. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2007-02-19 12:23:48
|
On 2/19/07, Roman Yakovenko <rom...@gm...> wrote: > > On 2/19/07, Gustavo Carneiro <gjc...@gm...> wrote: > > Even with the name mangling problem, something was not right: > > > > gjc@nazgul:python$ python test-schedule.py > > Traceback (most recent call last): > > File "test-schedule.py ", line 11, in <module> > > Simulator.Schedule_fbf096d706be19b392c1e3fbcd3bf544(t1, > > ev) > > Boost.Python.ArgumentError: Python argument types in > > > > Simulator.Schedule_fbf096d706be19b392c1e3fbcd3bf544(Time, > > MyEvent) > > did not match C++ signature: > > Schedule_fbf096d706be19b392c1e3fbcd3bf544(ns3::Time > > time, std::auto_ptr<ns3::EventImpl> event) > > > > Then I saw something I missed in the unit test, and added this code: > > > > EventImpl = mb.class_('EventImpl') > > EventImpl.held_type = 'std::auto_ptr< %s >' % EventImpl.decl_string > > > > (EventImpl is the type of the argument that is subject to the > ownership > > transfer) > > > > But with the above changes the code doesn't compile (errors > below). The > > generated source contains: > > > > bp::class_< EventImpl_wrapper, std::auto_ptr< ::ns3::EventImpl >, > > boost::noncopyable >( "EventImpl" ) > > .def( bp::init< >() ) > > > > The error comes from the ".def( bp::init< >() )" line. Manually > removing > > the "std::auto_ptr< ::ns3::EventImpl >" part from the first line solves > the > > compilation error. > > > > Any hints? > > Yes: > 1. change "std::auto_ptr< ::ns3::EventImpl >" to > "std::auto_ptr< EventImpl_wrapper >" and add next line to your code: > > ei = mb.class _( 'EventImpl' ) > ei.add_registration_code( > "boost::python::implicitly_convertible< std::auto_ptr< > EventImpl_wrapper >, std::auto_ptr< ::ns3::EventImpl > >();" > , False ) > > This should help. Thanks, Roman! I helped. 2. If not, please create small standalone test case, which reproduce the > problem. > I will take a look on it. Unfortunately after all this effort I am still experiencing similar memory errors as before. I don't understand why because, as far as I can tell, Py++ generated the boost code according to the boost FAQ advice. In this code, if I uncomment the 'del ev' line I get a memory error and segfault: from ns3 import * class MyEvent(EventImpl): def Notify(self): print "Notify!" ev = MyEvent() Simulator.Schedule(Seconds(1), ev) # takes ownership of ev #del ev Simulator.Run() # calls ev.Notify and then destroys it; memory error here Here's what valgrind reports: ==9790== Invalid read of size 4 ==9790== at 0x4B6E960: (within /usr/lib/libboost_python-gcc-mt-1_33_1.so.1.33.1) ==9790== by 0x8097F18: (within /usr/bin/python2.5) ==9790== by 0x8062CED: (within /usr/bin/python2.5) ==9790== by 0x4ABE032: boost::python::api::object_base::~object_base() (object_core.hpp:436) ==9790== by 0x4ABE080: boost::python::api::object::~object() (object_core.hpp:294) ==9790== by 0x4ABE176: boost::python::override::~override() (override.hpp :88) ==9790== by 0x4ADFC4F: EventImpl_wrapper::Notify() (ns3.cpp:32) ==9790== by 0x4AF9CF5: ns3::EventImpl::Invoke() (event-impl.cc:39) ==9790== by 0x4B005DE: ns3::SimulatorPrivate::ProcessOneEvent() ( simulator.cc:138) ==9790== by 0x4B0061E: ns3::SimulatorPrivate::Run() (simulator.cc:168) ==9790== Address 0x497D838 is 0 bytes inside a block of size 12 free'd ==9790== at 0x4020F9A: free (vg_replace_malloc.c:233) ==9790== by 0x4B6E766: boost::python::instance_holder::deallocate(_object*, void*) (in /usr/lib/libboost_python-gcc-mt-1_33_1.so.1.33.1) ==9790== by 0x4B6E97F: (within /usr/lib/libboost_python-gcc-mt-1_33_1.so.1.33.1) ==9790== by 0x8097F18: (within /usr/bin/python2.5) ==9790== by 0x8086418: PyDict_DelItem (in /usr/bin/python2.5) ==9790== by 0x8061656: PyObject_DelItem (in /usr/bin/python2.5) ==9790== by 0x80C27F9: PyEval_EvalFrameEx (in /usr/bin/python2.5) ==9790== by 0x80C60F4: PyEval_EvalCodeEx (in /usr/bin/python2.5) ==9790== by 0x80C6166: PyEval_EvalCode (in /usr/bin/python2.5) ==9790== by 0x80E590B: PyRun_FileExFlags (in /usr/bin/python2.5) I think I'll try to make a small example to reproduce this... -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Roman Y. <rom...@gm...> - 2007-02-19 19:04:11
|
Hi. Unfortunately I reproduced the error and was not able to fix it :-(((((. There is something I don't understand and I think this is Boost.Pythonbug. I do made some progress. 1. When you derive Python class from a C++ one you have to define __init__ method, otherwise your code will not work: class MyEvent(EventImpl): def __init__( self ): EventImpl.__init__( self ) def Notify(self): print "Notify!" 2. I did small research for you. Read this post: http://aspn.activestate.com/ASPN/Mail/Message/cpp-sig/1331901 and take a look on Boost.Python unit tests: http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.cpp?view=markup http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.py?view=markup What I found is: The ownership is really transfered. You can check this using simple technique: Add new function to EventImpl: virtual std::string class_name() const { return "EventImpl"; } Add free function: std::string get_class_name( const std::auto_ptr<EventImpl>& e ){ if( e.get() ){ return e->class_name(); } else{ return "no object"; } } You will get the answer "no object", after "Schedule" call. So, may be you don't have to delete the Python object. I will submit the bug to the Boost.Python mailing list, hope somebody will be able to help. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2007-02-20 00:03:17
|
On 2/19/07, Roman Yakovenko <rom...@gm...> wrote: > > Hi. Unfortunately I reproduced the error and was not able to fix it > :-(((((. Hey, thanks a lot anyway; it is now a problem in boost, but you solved the Py++ part of the problem with commendable speed. There is something I don't understand and I think this is Boost.Pythonbug. > > I do made some progress. > > 1. When you derive Python class from a C++ one you have to define __init__ > > method, otherwise your code will not work: Since when does a subclass have to define __init__ in order to get the parent class __init__ called? What you say goes against all my python knowledge... class MyEvent(EventImpl): > def __init__( self ): > EventImpl.__init__( self ) > > def Notify(self): > print "Notify!" > > 2. I did small research for you. Read this post: > http://aspn.activestate.com/ASPN/Mail/Message/cpp-sig/1331901 > and take a look on Boost.Python unit tests: > > http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.cpp?view=markup > > http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.py?view=markup > > What I found is: > The ownership is really transfered. You can check this using simple > technique: Add new function to EventImpl: > virtual std::string class_name() const { return "EventImpl"; } > Add free function: > std::string get_class_name( const std::auto_ptr<EventImpl>& e > ){ > if( e.get() ){ > return e->class_name(); > } > else{ > return "no object"; > } > } > You will get the answer "no object", after "Schedule" call. > So, may be you don't have to delete the Python object. I can't help it; I can't prevent the programmer from deleting the object prematurely; it's out of my control. I will submit the bug to the Boost.Python mailing list, hope somebody will > be able to help. Thanks, I will subscribe to that list too. -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Roman Y. <rom...@gm...> - 2007-02-20 06:42:25
|
On 2/20/07, Gustavo Carneiro <gjc...@gm...> wrote: > > On 2/19/07, Roman Yakovenko <rom...@gm...> wrote: > > > > Hi. Unfortunately I reproduced the error and was not able to fix it > > :-(((((. > > > Hey, thanks a lot anyway; it is now a problem in boost, but you solved > the Py++ part of the problem with commendable speed. > > There is something I don't understand and I think this is Boost.Pythonbug. > > > > I do made some progress. > > > > 1. When you derive Python class from a C++ one you have to define > > __init__ > > method, otherwise your code will not work: > > > Since when does a subclass have to define __init__ in order to get the > parent class __init__ called? What you say goes against all my python > knowledge... > During __init__ method of parent class reference to relevant Python object is saved and associated with the C++ class. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2007-02-20 11:34:46
|
On 2/20/07, Roman Yakovenko <rom...@gm...> wrote: > > On 2/20/07, Gustavo Carneiro <gjc...@gm...> wrote: > > > > On 2/19/07, Roman Yakovenko <rom...@gm... > wrote: > > > > > > Hi. Unfortunately I reproduced the error and was not able to fix it > > > :-(((((. > > > > > > Hey, thanks a lot anyway; it is now a problem in boost, but you solved > > the Py++ part of the problem with commendable speed. > > > > There is something I don't understand and I think this is > > > Boost.Python bug. > > > > > > I do made some progress. > > > > > > 1. When you derive Python class from a C++ one you have to define > > > __init__ > > > method, otherwise your code will not work: > > > > > > Since when does a subclass have to define __init__ in order to get the > > parent class __init__ called? What you say goes against all my python > > knowledge... > > > > During __init__ method of parent class reference to relevant Python object > is > saved and associated with the C++ class. > But if I don't define __init__ in a subclass, the parent class __init__ is automatically used instead, as demonstrated by this example: class Foo(object): def __init__(self): print "Foo.__init__" class Bar(Foo): pass bar = Bar() I think the problem you want to express is when Bar defines __init__ but doesn't chain to the parent class __init__. -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Gustavo C. <gjc...@gm...> - 2007-02-20 16:33:12
|
On 2/19/07, Roman Yakovenko <rom...@gm...> wrote: > > Hi. Unfortunately I reproduced the error and was not able to fix it > :-(((((. > There is something I don't understand and I think this is Boost.Pythonbug. > > I do made some progress. > > 1. When you derive Python class from a C++ one you have to define __init__ > > method, otherwise your code will not work: > > class MyEvent(EventImpl): > def __init__( self ): > EventImpl.__init__( self ) > > def Notify(self): > print "Notify!" > > 2. I did small research for you. Read this post: > http://aspn.activestate.com/ASPN/Mail/Message/cpp-sig/1331901 > and take a look on Boost.Python unit tests: > > http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.cpp?view=markup > > http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.py?view=markup > > What I found is: > The ownership is really transfered. You can check this using simple > technique: > Add new function to EventImpl: > virtual std::string class_name() const { return "EventImpl"; } > Add free function: > std::string get_class_name( const std::auto_ptr<EventImpl>& e > ){ > if( e.get() ){ > return e->class_name(); > } > else{ > return "no object"; > } > } > You will get the answer "no object", after "Schedule" call. > So, may be you don't have to delete the Python object. > > I will submit the bug to the Boost.Python mailing list, hope somebody will > be able to help. I found this wiki with a possible solution for the problem: http://wiki.python.org/moin/boost.python/HowTo#head-927c9493ac51c81b3f2484e486d85567ff316c8a Unfortunately the provided code, after adaptions to my case, didn't even compile :-( -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Gustavo C. <gjc...@gm...> - 2007-02-21 23:53:05
|
On 2/20/07, Gustavo Carneiro <gjc...@gm...> wrote: > > On 2/19/07, Roman Yakovenko <rom...@gm...> wrote: > > > > Hi. Unfortunately I reproduced the error and was not able to fix it > > :-(((((. > > There is something I don't understand and I think this is > > Boost.Python bug. > > > > I do made some progress. > > > > 1. When you derive Python class from a C++ one you have to define > > __init__ > > method, otherwise your code will not work: > > > > class MyEvent(EventImpl): > > def __init__( self ): > > EventImpl.__init__( self ) > > > > def Notify(self): > > print "Notify!" > > > > 2. I did small research for you. Read this post: > > http://aspn.activestate.com/ASPN/Mail/Message/cpp-sig/1331901 > > and take a look on Boost.Python unit tests: > > http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.cpp?view=markup > > > > http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.py?view=markup > > > > > > What I found is: > > The ownership is really transfered. You can check this using simple > > technique: > > Add new function to EventImpl: > > virtual std::string class_name() const { return "EventImpl"; } > > Add free function: > > std::string get_class_name( const std::auto_ptr<EventImpl>& e > > ){ > > if( e.get() ){ > > return e->class_name(); > > } > > else{ > > return "no object"; > > } > > } > > You will get the answer "no object", after "Schedule" call. > > So, may be you don't have to delete the Python object. > > > > I will submit the bug to the Boost.Python mailing list, hope somebody > > will be able to help. > > > I found this wiki with a possible solution for the problem: > > http://wiki.python.org/moin/boost.python/HowTo#head-927c9493ac51c81b3f2484e486d85567ff316c8a > > Good news. That wiki entry didn't apply anymore probably due to changing boost::python interfaces, but it provided very useful clues. I managed to get it working 100% correctly using another hack. Here's the diff of the manual changes I made to the wrapper: --- ns3.cpp 2007-02-21 23:46:44.000000000 +0000 +++ ns3-working.cpp 2007-02-21 23:44:34.000000000 +0000 @@ -9,19 +9,32 @@ namespace bp = boost::python; struct EventImpl_wrapper : ns3::EventImpl, bp::wrapper< ns3::EventImpl > { + ~EventImpl_wrapper() { + if (this->pyobj) { + Py_DECREF(this->pyobj); + this->pyobj = 0; + } + + } EventImpl_wrapper() : ns3::EventImpl() - , bp::wrapper< ns3::EventImpl >(){ - // null constructor + , bp::wrapper< ns3::EventImpl > (), pyobj(0) { } virtual void Notify( ){ + if (!this->pyobj) { + this->pyobj = bp::detail::wrapper_base_::get_owner(*this); + Py_INCREF(this->pyobj); + } bp::override func_Notify = this->get_override( "Notify" ); func_Notify( ); } +protected: + PyObject *pyobj; + }; static void Schedule_b8544467c482930a621aca2e7ac87dca( std::auto_ptr< ::ns3::EventImpl > event ){ Now my question, especially to any boost_python maintainers out there, can you please do something about this? I shouldn't have to make these kinds of hacks to get it working; any chance this INCREF/DECREF of the PyObject can make it upstream to the standard boost distribution? -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Roman Y. <rom...@gm...> - 2007-02-22 12:22:46
Attachments:
transfer_ownership.cpp
|
On 2/22/07, Gustavo Carneiro <gjc...@gm...> wrote: > That wiki entry didn't apply anymore probably due to changing > boost::python interfaces, but it provided very useful clues. I managed to > get it working 100% correctly using another hack. Here's the diff of the > manual changes I made to the wrapper: > > --- ns3.cpp 2007-02-21 23:46:44.000000000 +0000 > +++ ns3-working.cpp 2007-02-21 23:44:34.000000000 +0000 > @@ -9,19 +9,32 @@ > namespace bp = boost::python; > > struct EventImpl_wrapper : ns3::EventImpl, bp::wrapper< ns3::EventImpl > { > + ~EventImpl_wrapper() { > + if (this->pyobj) { > + Py_DECREF(this->pyobj); > + this->pyobj = 0; > + } > + > + } > > EventImpl_wrapper() > : ns3::EventImpl() > - , bp::wrapper< ns3::EventImpl >(){ > - // null constructor > + , bp::wrapper< ns3::EventImpl > (), pyobj(0) { > > } > > virtual void Notify( ){ > + if (!this->pyobj) { > + this->pyobj = > bp::detail::wrapper_base_::get_owner(*this); > + Py_INCREF(this->pyobj); > + } > bp::override func_Notify = this->get_override( "Notify" ); > func_Notify( ); > } > > +protected: > + PyObject *pyobj; > + > }; > > static void Schedule_b8544467c482930a621aca2e7ac87dca( > std::auto_ptr< ::ns3::EventImpl > event ){ > Hi Gustavo. I tested the code you post and it doesn't work for me :-(. I also doesn't understand how it works for you. You should increment reference on the object before you pass it "Schedule" member function, otherwise you get same "Segmentation fault". Am I missing something? I can avoid it by commenting the destructor code. Also I added new functionality, which allows you to implement the patch: http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/transfer_ownership_tester.py?view=markup http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/transfer_ownership_to_be_exported.hpp?view=markup I attached the generated code. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2007-02-24 12:57:52
|
On 2/22/07, Roman Yakovenko <rom...@gm...> wrote: > > On 2/22/07, Gustavo Carneiro <gjc...@gm...> wrote: > > That wiki entry didn't apply anymore probably due to changing > > boost::python interfaces, but it provided very useful clues. I managed > to > > get it working 100% correctly using another hack. Here's the diff of > the > > manual changes I made to the wrapper: > > > > --- ns3.cpp 2007-02-21 23:46:44.000000000 +0000 > > +++ ns3-working.cpp 2007-02-21 23:44:34.000000000 +0000 > > @@ -9,19 +9,32 @@ > > namespace bp = boost::python; > > > > struct EventImpl_wrapper : ns3::EventImpl, bp::wrapper< ns3::EventImpl > > { > > + ~EventImpl_wrapper() { > > + if (this->pyobj) { > > + Py_DECREF(this->pyobj); > > + this->pyobj = 0; > > + } > > + > > + } > > > > EventImpl_wrapper() > > : ns3::EventImpl() > > - , bp::wrapper< ns3::EventImpl >(){ > > - // null constructor > > + , bp::wrapper< ns3::EventImpl > (), pyobj(0) { > > > > } > > > > virtual void Notify( ){ > > + if (!this->pyobj) { > > + this->pyobj = > > bp::detail::wrapper_base_::get_owner(*this); > > + Py_INCREF(this->pyobj); > > + } > > bp::override func_Notify = this->get_override( "Notify" ); > > func_Notify( ); > > } > > > > +protected: > > + PyObject *pyobj; > > + > > }; > > > > static void Schedule_b8544467c482930a621aca2e7ac87dca( > > std::auto_ptr< ::ns3::EventImpl > event ){ > > > > Hi Gustavo. I tested the code you post and it doesn't work for me :-(. > I also doesn't understand how it works for you. You should increment > reference > on the object before you pass it "Schedule" member function, otherwise > you get same "Segmentation fault". Am I missing something? > I can avoid it by commenting the destructor code. You are right. In my case it worked due to a bug in my code. I forgot to make ~EventImpl() virtual, and so ~EventImpl_wrapper() was never called! :P I hate C++ :( Also I added new functionality, which allows you to implement the patch: > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/transfer_ownership_tester.py?view=markup > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/transfer_ownership_to_be_exported.hpp?view=markup Thanks, it works perfectly! :-) -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Gustavo C. <gjc...@gm...> - 2007-02-24 18:34:36
|
On 2/24/07, Gustavo Carneiro <gjc...@gm...> wrote: > > On 2/22/07, Roman Yakovenko <rom...@gm...> wrote: > > Also I added new functionality, which allows you to implement the patch: > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/transfer_ownership_tester.py?view=markup > > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/transfer_ownership_to_be_exported.hpp?view=markup > > > > > Thanks, it works perfectly! :-) > Bah, I spoke a little too soon :P It seems that when the virtual method is protected, as shown in the patch below, the "method.add_override_precall_code()" part stops having any effect on the generated virtual method code, and so the INCREF is not inserted, making the memory problem come back. And it so happens that the code I am trying to wrap hits precisely this bug... what a bad luck :( --- simulator.hpp 2007-02-19 12:55:53.000000000 +0000 +++ simulator-new.hpp 2007-02-24 18:29:12.000000000 +0000 @@ -7,6 +7,10 @@ namespace ns3 { class EventImpl { public: + void Invoke(void) { + Notify(); + } +protected: virtual void Notify() = 0; }; @@ -18,7 +22,7 @@ public: }; static void Run() { - Simulator::event->Notify(); + Simulator::event->Invoke(); delete Simulator::event; Simulator::event = 0; }; -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |
From: Roman Y. <rom...@gm...> - 2007-02-24 19:24:34
|
On 2/24/07, Gustavo Carneiro <gjc...@gm...> wrote: > On 2/24/07, Gustavo Carneiro <gjc...@gm...> wrote: > > > > On 2/22/07, Roman Yakovenko < rom...@gm...> wrote: > > > > > > > > > Also I added new functionality, which allows you to implement the patch: > > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/transfer_ownership_tester.py?view=markup > > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/transfer_ownership_to_be_exported.hpp?view=markup > > > > > > Thanks, it works perfectly! :-) > > Bah, I spoke a little too soon :P > > It seems that when the virtual method is protected, as shown in the > patch below, the " method.add_override_precall_code()" part > stops having any effect on the generated virtual method code, and so the > INCREF is not inserted, making the memory problem come back. And it so > happens that the code I am trying to wrap hits precisely this bug... what a > bad luck :( > > > --- simulator.hpp 2007-02-19 12:55:53.000000000 +0000 > +++ simulator-new.hpp 2007-02-24 18:29:12.000000000 +0000 > @@ -7,6 +7,10 @@ namespace ns3 { > class EventImpl > { > public: > + void Invoke(void) { > + Notify(); > + } > +protected: > virtual void Notify() = 0; > }; > > @@ -18,7 +22,7 @@ public: > }; > > static void Run() { > - Simulator::event->Notify(); > + Simulator::event->Invoke(); > delete Simulator::event; > Simulator::event = 0; > }; My fault and it is fixed now in SVN. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Gustavo C. <gjc...@gm...> - 2007-02-24 19:33:54
|
On 2/24/07, Roman Yakovenko <rom...@gm...> wrote: > > On 2/24/07, Gustavo Carneiro <gjc...@gm...> wrote: > > On 2/24/07, Gustavo Carneiro <gjc...@gm...> wrote: > > > > > > On 2/22/07, Roman Yakovenko < rom...@gm...> wrote: > > > > > > > > > > > > > Also I added new functionality, which allows you to implement the > patch: > > > > > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/transfer_ownership_tester.py?view=markup > > > > > > > http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/unittests/data/transfer_ownership_to_be_exported.hpp?view=markup > > > > > > > > > Thanks, it works perfectly! :-) > > > > Bah, I spoke a little too soon :P > > > > It seems that when the virtual method is protected, as shown in the > > patch below, the " method.add_override_precall_code()" part > > stops having any effect on the generated virtual method code, and so the > > INCREF is not inserted, making the memory problem come back. And it so > > happens that the code I am trying to wrap hits precisely this bug... > what a > > bad luck :( > > > > > > --- simulator.hpp 2007-02-19 12:55:53.000000000 +0000 > > +++ simulator-new.hpp 2007-02-24 18:29:12.000000000 +0000 > > @@ -7,6 +7,10 @@ namespace ns3 { > > class EventImpl > > { > > public: > > + void Invoke(void) { > > + Notify(); > > + } > > +protected: > > virtual void Notify() = 0; > > }; > > > > @@ -18,7 +22,7 @@ public: > > }; > > > > static void Run() { > > - Simulator::event->Notify(); > > + Simulator::event->Invoke(); > > delete Simulator::event; > > Simulator::event = 0; > > }; > > My fault and it is fixed now in SVN. It _really_ works now, thanks! :-) -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." |