[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