[C++-sig] Instantiate a wrapped class in C++ and get the PyObject pointer

Stefan Seefeld seefeld at sympatico.ca
Mon Apr 23 23:29:39 CEST 2007

David Sveningsson wrote:

> PyObject* foo(){
>   boost::python::object bar = Fred(1,2,3);	// <-- Stack allocated
>   return bar.ptr();
> }
> Since bar is allocated on the stack it will be destroyed once we return
> from bar. Won't the pointer returned by ptr() only point to garbage after
> returning?

python's objects are all heap-allocated (and ref-counted). The above
boost::python::object is only a tiny wrapper around a PyObject pointer,
conveniently handling the ref counting for you.
I'd think the construction itself thus already implies a copy construction
to move the Fred instance into the heap.
You are right that simply returning bar.ptr() like this is wrong, due to
python potentially (or even likely) deleting the underlaying object, as soon
as bar's destructor decreases the ref counter at the end-of-scope.

Thus, you need to increment the counter before returning. However, the
whole point of boost.python is to discourage you to use PyObject pointers
directly (given how error-prone a business this is).

> PyObject* foo(){
>   boost::python::object bar = new boost::python::object(Fred(1,2,3));
>   return bar->ptr();
> }
> This time bar is allocated on the heap, so the pointer would still be
> valid after returning from bar. But it will leak memory.

Right. Don't do that. boost::python::object instances should be allocated
on the stack, and always be passed by-value.



      ...ich hab' noch einen Koffer in Berlin...

More information about the Cplusplus-sig mailing list