From Patrick Hartling, "I encountered a bug related to RTTI for subclasses of osg::Shape. The

circumstances under which this bug occur are rather specific, but the
basic problem occurs when one translation unit other than libosg.so
constructs an object that is a subclass of osg::Shape and another
translation unit other than libosg.so tries to perform a dynamic_cast or
other RTTI-based operation on that object. Under these circumstances,
the RTTI operation will fail. In my case, the translation units involved
were an application and osgdb_ive.so. The application constructed a
scene graph that included instantiations of subclasses of osg::Shape.
Depending on how the user ran the application, it would write the scene
graph to an IVE file using osgDB::writeNodeFile(). The dynamic_cast
operations in DataOutputStream::writeShape() would fail on the first
subclass of osg::Shape that was encountered. This is because there were
two different RTTI data objects for all osg::Shape subclasses being
compared: one in the application and one in osgdb_ive.so.

The fix for this is simple. We must ensure that at least one member
function of each of the subclasses of the polymorphic type osg::Shape is
compiled into libosg.so so that there is exactly one RTTI object for
that type in libosg.so. Then, all code linking against libosg.so will
use that single RTTI object. The following message from a list archive
sort of explains the issue and the solution:

  http://aspn.activestate.com/ASPN/Mail/Message/1688156

While the posting has to do with Boost.Python, the problem applies to
C++ libraries in general."
This commit is contained in:
Robert Osfield 2009-01-28 09:21:46 +00:00
parent 998582e945
commit a51e95222d
2 changed files with 65 additions and 22 deletions

View File

@ -99,12 +99,12 @@ class HeightField;
class CompositeShape; class CompositeShape;
class ShapeVisitor class OSG_EXPORT ShapeVisitor
{ {
public: public:
ShapeVisitor() {} ShapeVisitor() {}
virtual ~ShapeVisitor() {} virtual ~ShapeVisitor();
virtual void apply(Shape&) {} virtual void apply(Shape&) {}
virtual void apply(Sphere&) {} virtual void apply(Sphere&) {}
@ -121,12 +121,12 @@ class ShapeVisitor
virtual void apply(CompositeShape&) {} virtual void apply(CompositeShape&) {}
}; };
class ConstShapeVisitor class OSG_EXPORT ConstShapeVisitor
{ {
public: public:
ConstShapeVisitor() {} ConstShapeVisitor() {}
virtual ~ConstShapeVisitor() {} virtual ~ConstShapeVisitor();
virtual void apply(const Shape&) {} virtual void apply(const Shape&) {}
virtual void apply(const Sphere&) {} virtual void apply(const Sphere&) {}
@ -143,7 +143,7 @@ class ConstShapeVisitor
virtual void apply(const CompositeShape&) {} virtual void apply(const CompositeShape&) {}
}; };
class Sphere : public Shape class OSG_EXPORT Sphere : public Shape
{ {
public: public:
@ -178,14 +178,14 @@ class Sphere : public Shape
protected: protected:
virtual ~Sphere() {} virtual ~Sphere();
Vec3 _center; Vec3 _center;
float _radius; float _radius;
}; };
class Box : public Shape class OSG_EXPORT Box : public Shape
{ {
public: public:
@ -230,7 +230,7 @@ class Box : public Shape
protected: protected:
virtual ~Box() {} virtual ~Box();
Vec3 _center; Vec3 _center;
Vec3 _halfLengths; Vec3 _halfLengths;
@ -240,7 +240,7 @@ class Box : public Shape
class Cone : public Shape class OSG_EXPORT Cone : public Shape
{ {
public: public:
@ -291,7 +291,7 @@ class Cone : public Shape
protected: protected:
virtual ~Cone() {} virtual ~Cone();
Vec3 _center; Vec3 _center;
float _radius; float _radius;
@ -300,7 +300,7 @@ class Cone : public Shape
Quat _rotation; Quat _rotation;
}; };
class Cylinder : public Shape class OSG_EXPORT Cylinder : public Shape
{ {
public: public:
@ -348,7 +348,7 @@ class Cylinder : public Shape
protected: protected:
virtual ~Cylinder() {} virtual ~Cylinder();
Vec3 _center; Vec3 _center;
float _radius; float _radius;
@ -356,7 +356,7 @@ class Cylinder : public Shape
Quat _rotation; Quat _rotation;
}; };
class Capsule : public Shape class OSG_EXPORT Capsule : public Shape
{ {
public: public:
@ -404,7 +404,7 @@ class Capsule : public Shape
protected: protected:
virtual ~Capsule() {} virtual ~Capsule();
Vec3 _center; Vec3 _center;
float _radius; float _radius;
@ -412,7 +412,7 @@ class Capsule : public Shape
Quat _rotation; Quat _rotation;
}; };
class InfinitePlane : public Shape, public Plane class OSG_EXPORT InfinitePlane : public Shape, public Plane
{ {
public: public:
InfinitePlane() {} InfinitePlane() {}
@ -425,10 +425,10 @@ class InfinitePlane : public Shape, public Plane
protected: protected:
virtual ~InfinitePlane() {} virtual ~InfinitePlane();
}; };
class TriangleMesh : public Shape class OSG_EXPORT TriangleMesh : public Shape
{ {
public: public:
@ -453,14 +453,14 @@ class TriangleMesh : public Shape
protected: protected:
~TriangleMesh() {} virtual ~TriangleMesh();
ref_ptr<Vec3Array> _vertices; ref_ptr<Vec3Array> _vertices;
ref_ptr<IndexArray> _indices; ref_ptr<IndexArray> _indices;
}; };
class ConvexHull : public TriangleMesh class OSG_EXPORT ConvexHull : public TriangleMesh
{ {
public: public:
@ -473,7 +473,7 @@ class ConvexHull : public TriangleMesh
protected: protected:
~ConvexHull() {} virtual ~ConvexHull();
}; };
class OSG_EXPORT HeightField : public Shape class OSG_EXPORT HeightField : public Shape
@ -583,7 +583,7 @@ class OSG_EXPORT HeightField : public Shape
typedef HeightField Grid; typedef HeightField Grid;
class CompositeShape : public Shape class OSG_EXPORT CompositeShape : public Shape
{ {
public: public:
@ -637,7 +637,7 @@ class CompositeShape : public Shape
protected: protected:
~CompositeShape() {} virtual ~CompositeShape();
ref_ptr<Shape> _shape; ref_ptr<Shape> _shape;
ChildList _children; ChildList _children;

View File

@ -19,6 +19,46 @@ Shape::~Shape()
{ {
} }
ShapeVisitor::~ShapeVisitor()
{
}
ConstShapeVisitor::~ConstShapeVisitor()
{
}
Sphere::~Sphere()
{
}
Box::~Box()
{
}
Cone::~Cone()
{
}
Cylinder::~Cylinder()
{
}
Capsule::~Capsule()
{
}
InfinitePlane::~InfinitePlane()
{
}
TriangleMesh::~TriangleMesh()
{
}
ConvexHull::~ConvexHull()
{
}
HeightField::HeightField(): HeightField::HeightField():
_columns(0), _columns(0),
_rows(0), _rows(0),
@ -129,4 +169,7 @@ Vec2 HeightField::getHeightDelta(unsigned int c,unsigned int r) const
return heightDelta; return heightDelta;
} }
CompositeShape::~CompositeShape()
{
}