[C++-sig] Chaining methods in C++ and Python

David Abrahams dave at boost-consulting.com
Wed Mar 5 20:14:49 CET 2003


Alexey Goldin <Alexey.Goldin at jpl.nasa.gov> writes:

>> 
>> This is a simple issue of lifetime management.  The C++ 'a' objects
>> created in mk_tst are owned by their corresponding Python objects,
>> which get destroyed when mk_tst exits.  The pointers you have stored
>> in your 'tst' object are dangling thereafter.
>> 
>> The Introduction section at
>> http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/with_custodian_and_ward.html#introduction
>> explains this fairly well
>> 
>> HTH,
>
> Ok. This makes sense. 

Agh, no it doesn't, sorry.  I mis-analyzed the actual problem.

The deal is that the result of t.set_f1(a1) looks like this:

           result        t2             a1
         +-------+    +-------+    +-------+
Python   |  tst  +===>|  tst  +===>|   a   |
         +-------+    +-------+    +-------+    
C++      |   *   |    |  tst  |    |   a   |
         +---+---+    +-------+    +-------+    
             |            ^
             +------------+


Where double arrows are ownership, and the single arrow represents
the reference to the C++ object inside of t2.

then, result.set_f2(a2) causes something like this:

                               ++==========================++              
          result2      result1 ||     t2           a1      ||      a2      
         +-------+    +-------+||  +-------+    +-------+  ||   +-------+  
Python   |  tst  +===>|  tst  +++=>|  tst  +===>|   a   |  ++==>|   a   |  
         +-------+    +-------+    +-------+    +-------+       +-------+  
C++      |   *   |    |   *   |    |  tst  |    |   a   |       |   a   |  
         +---+---+    +---+---+    +-------+    +-------+       +-------+  
             |            |            ^                                   
             +----------->+------------+                                   

As you can see the lifetime of a2 isn't maintained by t2 when it is
returned.

The key is to somehow get the set_f1() and set_f2() to return the
original Python tst object instead of a "shadow".

There are lots of ways to do that, but probably the easiest is to use
back_reference<tst> in a thin wrapper function:

  object set_f1(back_reference<tst&> self, A & ff)
  {
     self.get().set_f1(ff); 
     return self;
  };

  ...

    .def("set_f1", set_f1,  with_custodian_and_ward<1,2>() )

attached is a full demo.

The question remains open as to whether Boost.Python should be doing
something for you automatically here.  I think
return_internal_reference might include a test to see if it's the
same object being returned, and handle this automatically.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: test.cpp
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20030305/08111300/attachment.txt>
-------------- next part --------------


> However --- is it possible to do one of the
> following things in not too ugly way:
>
> 1) allow writing something like t.set_f1(a1).set_f2(a2) and make sure
> that pointers to both a1 and a2 are owned by t --- preferable solution
>
> 2) Making sure that t.set_f1(a1) does not return object of type tst, so
> calling 
> t.set_f1(a1).set_f2(a2) and instead I have to call 
>
> t.set_f1(a1)
> t.set_f2(a2)
>
>  --- not so good, but at least making sure it is not easy to crash
> application?
>
> I can not change signature of method tst::set_f1 --- this is a library
> not under my control. Yes, I can write some wrappers but in my
> understanding this is what boost.python was created to avoid....
>
> Thank you! boost.python is a wonderful tool, but sometimes as confusing
> as C++ :-)
>
> -- 
> Alexey Goldin <Alexey.Goldin at jpl.nasa.gov>
>
>
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com


More information about the Cplusplus-sig mailing list