[C++-sig] Pointer to existing Python object

Andreas Beyer beyer at imb-jena.de
Tue Apr 12 04:45:18 CEST 2005


Hi:

I know that there has been some discussion on this subject on c++ sig. 
However, I could not find a solution for my specific problem and maybe 
there is no solution.

Here we go:
I have a container class B that creates instances of class A - both in 
C++. In Python I can get instances of A from B with a get() method. I 
would like to get an existing Python object whenever such object existis 
and I would like to get a new Python object if no Python object for A 
exists.

An example:


using namespace boost;

class A : public enable_shared_from_this<A> {
  public:
     A() : val(0) {};
     int val;
     typedef shared_ptr<A> A_ptr;
     A_ptr self() {
        A_ptr self;
        self = shared_from_this();
        return self;
      }

};


class B {
    public:
      B() {
           a = A::A_ptr(new A());
      }
      A::A_ptr a;
      void set(A::A_ptr a) {
          this->a = a;
      }

      A::A_ptr get() {
          return a->self();
      }
};


BOOST_PYTHON_MODULE(ptr_test) {
  python::class_<A> ("A")
    .def_readwrite("val", &A::val)
  ;
  python::register_ptr_to_python< A::A_ptr >();
 
  python::class_<B>("B")
     .def("set", &B::set)
     .def("get", &B::get)
  ;
}


In Python I would like to do this:

 >>> b = B()
 >>> a1 = b.get() # obtain instance of class A
 >>> a2 = b.get() # get the *same Python instance* again
 >>> assert(a1==a2)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError
 >>>

The internal representations of instances of A are the same! Whenever I 
access a C++ member of A I am actually accessing the same object.  So I 
can do this:
 >>> a1.val = 42 # change internal reference
 >>> print a2.val
42
 >>>
However, I cannot do this:
 >>> a1.foo = 42
 >>> print a2.foo
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'A' object has no attribute 'foo'
 >>>

I think instances of B have to check if there is already an existing 
Python object. In that case  B (or a wrapper of B) should return the 
existing Python object (i.e. instances of python::object). Is there a 
way to find such an existing instance?

Andreas





More information about the Cplusplus-sig mailing list