[C++-sig] boost::python::object referencing c++ object
David Abrahams
dave at boost-consulting.com
Fri Jan 3 21:24:45 CET 2003
"Bjorn Pettersen" <BPettersen at NAREX.com> writes:
> I've got the following code to assign a wrapped object to a Python
> variable:
>
> template <class T>
> void set(const std::string& name, const T& value) {
> PyObject* key = PyString_FromString(name.c_str());
> object val(value);
> PyDict_SetItem(interpreter()->mainmodule(), key, val.ptr());
> Py_DECREF(key);
> }
Why make life hard for yourself?
template <class T>
void set(const std::string& name, const T& value) {
interpreter()->mainmodule()[name] = value;
}
Of course, this relies on interpeter()->mainmodule() returning an
object (or dict, or...)
> and I'd like to be able to set() a variable to a c++ object, then later
> mutate the object and have the changes visible to Python. I haven't
> traced through the code completely, but it looks like the object ctor
> makes a copy(?)
More precisely, it converts its argument into a Python object.
If your C++ object is a wrapped class type, it will be copied.
> Is there any way to accomplish what I'd like to do?
I'm not sure exactly what you want.
Perhaps you'd like the resulting Python object to contain a raw
pointer to the argument? In that case, the caveat is that if the
lifetime of the C++ object ends before that of the Python object, that
pointer will dangle and using the Python object may cause a crash.
There is a way to do that, but it's more convoluted than it should be:
template <class T>
T& identity(T& x)
{
return x;
}
template <class T>
object get_object_reference(T& x)
{
// build a function object around identity
object f
= make_function(
&identity<T>, return_value_policy<reference_existing_object>());
// and call
return f(x);
}
HTH,
--
David Abrahams
dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution
More information about the Cplusplus-sig
mailing list