[C++-sig] Inconsistency with Boost.Python code
Stefan Seefeld
seefeld at sympatico.ca
Thu Oct 9 20:11:52 CEST 2008
Robert wrote:
>
> Will this code below work?
>
> boost::python::dict GetNamespace( char const* mod )
> {
> using namespace boost::python;
> dict moduleNamespace( extract<dict>( import( mod ).attr(
> "__dict__" ) ) );
> return moduleNamespace;
> }
>
>
> My main concern is the returned value of "import()" going out of scope
> and being destroyed since there are no outstanding references to it,
> causing the dict object returned to reference an invalid object. Would
> this be a possibility?
No. moduleNamespace holds a (counted) reference to the module object, so
it won't be destroyed (unloaded) while someone still holds references to
objects within it.
>
> After running the code above I find that it does not work, and I get
> the following output from python:
>
> TypeError: No to_python (by-value) converter found for C++ type:
> struct boost::python::extract<class boost::python::dict>
That's probably caused by the above code being a little too compact.
extract<dict> is actually a distinct type, which provides a conversion
operator for 'dict'. (This two-phase conversion is useful as you may
not yet know whether the conversion would succeed, so the extract<> type
gives you an opportunity to check that, before actually invoking it.)
In most circumstances this conversion operator is invoked implicitly by
the compiler, but sometimes it isn't.
A slight change in the syntax should do the trick, such as
dict moduleNamespace = extract<dict>( import( mod ).attr( "__dict__" )
); // caution: untested !
or applying the call operator on the temporary extract<> object:
dict moduleNamespace(extract<dict>(import(mod).attr("__dict__")(); //
caution: untested !
HTH,
Stefan
--
...ich hab' noch einen Koffer in Berlin...
More information about the Cplusplus-sig
mailing list