[C++-sig] Calling list.__len__() from C++ causes crash with >= 100 elements
Alex Mohr
amohr at pixar.com
Mon Aug 7 18:46:18 CEST 2006
>> void printListLength(boost::python::object elements)
>> {
>> boost::python::extract<int> lenExtract( elements.attr( "__len__" )() );
>> if ( lenExtract.check() )
>> {
>> int numElements = lenExtract;
>> std::cout << numElements << " elements" << std::endl;
>> }
>> }
>
> I can reproduce your problem under FC3 and FC5 (both x86_64). I am not sure if
> this is a bug or a feature. In any case, this workaround does the trick for me:
It is apparently a feature. We've had a similar bug before as well.
You're creating a c++ temporary holding a new python object when you do
"elements.attr("__len__")()" and passing it off to the extractor, and
then you attempt to invoke the extractor later after the c++ temporary
has died.
The problem is that the extractor does not keep a reference to the
python object it was constructed with (and is documented accordingly).
So, by the time you invoke the extractor, the python object it's got is
long since dead, and you get a crash.
The fix posted in the parent message is the correct one. You need to
make sure the object you pass to the extractor lives at least as long as
the last invocation of the extractor.
Here's the documentation:
http://www.boost.org/libs/python/doc/v2/extract.html#extract-spec
Note this sentence:
"Stores a pointer to the Python object managed by its constructor
argument. In particular, the reference count of the object is not
incremented. The onus is on the user to be sure it is not destroyed
before the extractor's conversion function is called."
When we came across this, we wondered why it would be bad for the
extractor to take a reference to its argument. David -- can you shed
some light on this?
Alex
More information about the Cplusplus-sig
mailing list