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

Andreas Beyer beyer at imb-jena.de
Mon Apr 18 21:02:33 CEST 2005


Well, still no response, maybe the issue is really tough. I keep 
thinking about it, this is my current state:

It is already possible to obtain smart pointers for objects that are 
created in the Python environment. Coming back to my initial example:
http://mail.python.org/pipermail/c++-sig/2005-April/008787.html
I can create 'A's in Python, pass them to instances of B and B::get() 
will return the same *Python* object. I think this feature is enabled by
python::register_ptr_to_python< A::A_ptr >();

I am looking for the reverse, objects A created by instances of B (i.e. 
inside C++) need to be recognized by boost::python whenever the Python 
environment asks for them. That means, whenever instances of B return a 
smart pointer to an object for which a Python object exists already, 
that existing Python object should be returned. For objects created in 
the C++ environment this means, the first call to B::get() should return 
a new Python wrapper, subsequent calls should return the existing 
object. This could become tricky. E.g., this concept may not work for 
all kinds of return policies. However, I am looking for a specific 
solution for my code, where it may be possible to circumvent these 
difficulties.
It should be possible to implement the idea by defining a 
to_python_converter for A_ptr. That to_python_converter had to check for 
existing Pyhon objects. I tried a few things, but so-far I was 
unsuccessfull. Could somebody give me advice on how to proceed?

1. Are my thoughts on the right track?
2. I never wrote a to_python_converter. I am not even sure I have to: 
converting A* to Python with the default mechanism is no problem. In 
fact I want to wrap the A_ptr -> Python conversion. Can I somehow use 
the existing boost::python tools for converting A* inside my custom 
converter? How?
3. Is there an existing solution for a similar problem on which I could 
expand on?

Thanks!!
  Andreas

PS: Another difficulty: The wrapper that I am thinking of would manage 
some kind of global map, which maps pointers A* to their respective 
python wrappers. Pointers not in the map would get new python wrappers. 
But what about objects that are deleted? How gets my code informed about 
this? If I don't delete those entries from the map, the map will keep 
growing and growing. Is there a solution without changing ~A()?


Andreas Beyer wrote:

> Hi,
>
> I just want to bring this issue back on the table. I still didn't get 
> a brilliant idea how to solve it.
>
> So far, I see only this option:
> - Wrap B, in particular wrap B.get().
> - In get() create the actual python object, like:
>    python::object py_a(B::get());
> - Store those objects in a map.
> - When B_wrap.get() gets called again, check if a python object 
> already exists and return it.
>
> However, in my real-world application I had to wrap quite a lot of 
> methods returning As. I also have methods returning vectors of A_ptr, 
> which makes it even more enoying. (I would have to wrap the 
> vector<A_ptr>, too.)
>
> What is this has_back_reference doing? Is that somehow related to my 
> problem? (I regret that I don't really understand what it is doing, as 
> I don't know what a "predicate metafunction" is.)
> Just adopting the example at 
> http://www.boost.org/libs/python/doc/v2/has_back_reference.html is not 
> really a solution, because my instances of A are created inside the 
> C++ code (by factory methods in class B). I would have to be very 
> intrusive and make the actual class B aware of Python/boost::python 
> for adopting the above solution.
>
> I know that boost::python is collecting the shared pointers somewhere. 
> Is it possible to use that mechanism somewhow for solving my problem? 
> Any ideas?
>
> Thanks!!
>    Andreas
>
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig
>




More information about the Cplusplus-sig mailing list