[C++-sig] A little "Pure virtual function called" help...

Allen Bierbaum abierbaum at gmail.com
Mon Oct 9 17:55:55 CEST 2006


I have a rather frustrating problem in a binding I am trying to
extend.  It is inside a rather complex binding that is partially
described here:
http://thread.gmane.org/gmane.comp.python.c++/10125/focus=10125

It is complex because I am using custom smart pointers and it is
wrapping a very large library so coming up with a small test case has
been difficult.  In fact the small from scratch test case I created
worked which was surprising.

I have a Geometry class that has a set of methods that return access
to geometry properties.  For example it may return an object that
holds a list of positions in space.  These positions could be in any
number of formats (float, double, int, etc)  so the library returns a
base class that acts as an adapter and provides uniform access to all
the various possible formats.  All of these classes are in C++ so
although I do have the wrapper types generated by Py++, I don't think
they are relevant to this discussion.

The format hierarchy has classes like this:

class GeoVectorProperty
{
....
void setValue( variant_type, 0);
virtual unsigned getSize() = 0;
};

class GeoVectorPropertyVec3f  : public GeoVectorProperty
{
 ....
 virtual unsigned getSize();
}

I have successfully wrapped GeoVectorProperty but I would like to
avoid wrapping all of the numerous implementations of the "real"
types.  Instead I want to just keep using the base adapter interface
and calling those methods to access the data.

I thought things were good until I tried the code in python:

>>> g
<osg2._osg2.Geometry object at 0xb78571ec>
>>> pos = g.getPositions()
>>> pos
<osg2._osg2.GeoVectorProperty object at 0xb785722c>
>>> pos.size()
Traceback (most recent call last):
 File "<input>", line 1, in ?
RuntimeError: Pure virtual function called
>>> pos.setValue(osg2.Vec3f(0,0,0), 1)

The problem seems to be that for some reason the pure virtual method
"size" is not being called correctly.  I know that the class behind
the scenes for "pos" is a derived type because the "setValue" method
uses the virtual methods internally in the C++ code.

At first I thought that maybe Py++ was not wrapping this correctly but
I created a simple test cases with 2 classes and a factory function
that when wrapped worked correctly when calling a pure virtual of a
base class.

To make matters a little stranger, I found that if I edit the pure
virtual method GeoVectorProperty::getSize() and make it none pure by
returning 0, then everything works as expected.

So I am left wondering where to turn next?  I am suspicious that
possibly the python object "pos" doesn't have a pointer type that is
able to handle this correctly.  It should, but that code is deep
inside the smart_pointer wrappers and boost.python conversion code and
I don't have any way to verify what the type is.

So my question is, what should I look for next?  Any hints as to how
to try to debug this problem?

Thanks,
Allen



More information about the Cplusplus-sig mailing list