On 2/20/07, Gustavo Carneiro <gjcarneiro@gmail.com> wrote:
On 2/19/07, Roman Yakovenko <roman.yakovenko@gmail.com > 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."