[C++-sig] return reference to same python object

Jonge, W. de (Cebra) W.d.Jonge at cebra.tue.nl
Fri Jan 6 12:12:55 CET 2006


Hi,

If BP already has the required info internally all the better to use it.
I've been trying to create a working sample based on your information,
however it doesn't work. My code (this is with hold_python for every
object retrieval, I also tried calling the hold python once during
construction as you suggested, also without any success):

using namespace boost;

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

template <class T>
hold_python(shared_ptr<T>& x)
{
	x = python::extract<shared_ptr<T> >( python::object(x) );
}

A::A_ptr a;

A::A_ptr get_a()
{
	hold_python(a);
	return a;
}

BOOST_PYTHON_MODULE(mymod)
{
	// create single instance
	a = A::A_ptr(new A);

	python::register_ptr_to_python< A::A_ptr >();

	python::class_<A> ("A")
		.def_readwrite("val", &A::val)
	;

	python::def("get", get_a);
}

The script I'm running:

import mymod

a1 = mymod.get()
a2 = mymod.get()

a1.val = 3
a1.foo = 42

print a2.val
print a2.foo

Giving me this:

3
Traceback (most recent call last):
  File "test.py", line 10, in ?
    print a2.foo
AttributeError: 'A' object has no attribute 'foo'

Thanks,

Willem

> -----Original Message-----
> From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org]
On
> Behalf Of Andreas Beyer
> Sent: Wednesday, January 04, 2006 4:29 PM
> To: Development of Python/C++ integration
> Subject: Re: [C++-sig] return reference to same python object
> 
> Jonge, W. de (Cebra) wrote:
> 
> >Hi Andreas,
> >
> >Thanks for the reply, as my objects are created in C++ space I think
the
> >latter thread applies
> >(http://mail.python.org/pipermail/c++-sig/2005-April/008805.html).
> >Did you ever got something working, and if so how?
> >
> If you exactly follow David's suggestions it works. The example that I
> gave works with David's solution.
> 
> >With or without using
> >the to_python_converter, this sounds as a good solution to me and I
> >would also think to use a global map mapping C++ pointers to already
> >existing python wrappers.
> >
> >
> I recommend *not* to create a map for C++ pointers. You are doubbling
> information that BP already has. You also don't gain a lot. In order
to
> use the map, you will have to check if a certain smart pointer is
> already registered in the map before you return it to python. (You
will
> do this in some kind of thin-wrapper function.) At the same point in
> your code you could also just call hold_python() - it does the job for
> you.
> The problem here: you have to create a wrapper for all functions
> returning the smart pointers.
> 
> I never created a to_python_converter (don't know how to do that).
> However, you may not need it anyway.
> My workaround is: call hold_python() immediately after creating an
> object. Afterwards BP 'knows' the respective smart pointer. There is
no
> need to call hold_python() at any other location in your code.
> The drawback: I couldn't find a way (in my code) that is not intrusive
> into the originial C++ code. What I am doing now is something like
this:
> 
> A_ptr my_factory_method()
> {  // this is my original factory method, which I had to modify
>     A_ptr * a = create_new_A();
> #ifdef BP_WRAPPING
>     hold_python(a); // register new smart pointer at boost.python
> #endif
>     return a;
> }
> 
> 
> Of course you have to define BP_WRAPPING and hold_python() somewhere.
> I am sure there are better solutions. Yet, I don't know them.
> 
> 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