[C++-sig] Lifetime of Python object for a pointer argument
David Abrahams
david.abrahams at rcn.com
Sat Feb 16 17:41:20 CET 2002
Your analysis of what's going wrong here is correct. There is a way to make
what you're doing "work" with Boost.Python V1, but it's ugly. You have to
wrap geometry with a "callback" class as though it had virtual
functions(www.boost.org/libs/python/doc/overriding.html):
// Warning: off-the-cuff, untested
struct geometry_callback : geometry
{
geometry(PyObject* self, PyObject* grid_obj)
: grid_obj(grid_obj)
{ Py_XINCREF(grid_obj); }
~geometry() { Py_XDECREF(grid_obj); }
PyObject* grid_obj;
};
python::class_builder<geometry, geometry_callback>
geometry_class(this_module, "geometry");
...
but note, that your to_python(const grid*) function also results in the grid
being /copied/ (probably not what you want). Boost.Python V2 (currently in
prerelease) provides a better approach:
BOOST_PYTHON_MODULE_INIT(ngf2)
{
python::module("ngf2)
.add(
class<grid>("grid")
.def_init()
)
.add(
class<geometry>("geometry")
.def_init(args<const grid*>()
// Keep the grid alive as long as the geometry is.
, python::with_custodian_and_ward<1,2>())
.def("getGrid", &geometry::getGrid
// keep the geometry object alive as long as the result is
, python::return_internal_reference<>())
);
}
----- Original Message -----
From: "Min Xu" <minxu at sci.ccny.cuny.edu>
> Hi,
>
> I am a newbie of boost python. In the process of converting a SWIG
> wrapping of a C++ library to boost python, I encounter the following
> problem:
>
> // C++ part
> class grid
> {
> public:
> grid() { ... }
> ...
> };
>
> class geometry
>
> public:
> geometry(const grid * gd) : gd(gd) {}
> const grid* getGrid() const { return gd; }
> private:
> const grid* gd;
> };
>
> // Wrapper
> #include <boost/python/class_builder.hpp>
> namespace python = boost::python;
>
> PyObject* to_python(const grid* g) {
> return to_python(*g); // convert const grid* in terms of const
> grid&
> }
>
> BOOST_PYTHON_MODULE_INIT(ngf2)
> {
> try
> {
> python::module_builder this_module("ngf2");
> python::class_builder<grid> grid_class(this_module, "grid");
> grid_class.def(python::constructor<>());
> python::class_builder<geometry> geometry_class(this_module,
> "geometry");
> geometry_class.def(python::constructor<const grid*>());
> }
> ...
> }
>
> The compilation works well (the newest CVS version of boost python).
> In python:
> >>> from ngf2 import *
> >>> a=geometry (grid())
> >>> a.getGrid ().a()
> 8.6723632812500586 # corrupted as grid() is deleted automatically?
> >>> g=grid()
> >>> b=geometry (g)
> >>> b.getGrid ().a()
> 1.0 # expected.
> >>> del g
> >>> b.getGrid ().a()
> 1.3285421879284814e-269 # corrupted
>
> I understand it may be a ref counting problem. Is there any way to make
> the first idiom work?
>
> Thanks!
>
>
> Min Xu
>
>
>
>
>
> _______________________________________________
> 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