Dear List,

when I use dynamic cast from two boost modules on a class with "vague
linkage", in my real use case a template in the simplified example I
show you a class which is declared inline, then the dynamic cast fails
in the second module.

So when I call the code from python from the first module (in which
the Vertex object has been created), then the dynamic cast succeeds:

"calling performTest(m) ...
I am a Vertex"

but when I do the same from the other module, then I get

"calling performTest2(m) ...
dynamic cast failed, I got the object:
I am a Vertex"

I attached a very simple example in the files:
  bugDynamicCastSimplified.h (declares the Classes VerboseObject,
Vertex and Mesh)
  bugDynamicCastPy.cpp (first boost module)
  bugDynamicCast2Py.cpp (second boost module)

The problem dissapears without the vague linkage, e.g. when you define
REMOVE_INLINE_DEFINITION in the code. This is not a very nice  option
for me, as in my real use case Vertex is a template, and this would
force me to initialize it for each type.

My gcc is:
> g++ --version
g++ (Gentoo 4.4.5 p1.2, pie-0.4.5) 4.4.5

And I am building the project with cmake (not boost). I read the FAQ
entry at http://gcc.gnu.org/faq.html#dso and added "-Wl,-E" to
CMAKE_SHARED_LINKER_FLAGS. About the RTLD_GLOBAL flag for dlopen, I
don't know how python handles this.

Do you have any ideas how to solve this? Or is this simply not
possible with python?

-Holger
#pragma once

#include "iostream"

struct VerboseObject {
  virtual void describe() = 0;
};

//#define REMOVE_INLINE_DEFINITION
#ifndef REMOVE_VIRTUAL_INHERITANCE
struct Vertex : public VerboseObject 
{
  virtual void describe() {
    std::cout << "I am a Vertex" << std::endl;
  }
};
#else
struct Vertex : public VerboseObject 
{
  virtual void describe();
};
#endif

struct Mesh {
  Mesh() {
    bulk = new Vertex();
  }

  ~Mesh() {
    delete bulk;
  }

  template<class T>
  T* getBulk() const
  {
    return dynamic_cast<T*>(bulk);
  }

  VerboseObject* getBulk() const
  {
    return bulk;
  }

  static void performTest(const Mesh& m) {
    VerboseObject* o = m.getBulk();
    Vertex* v =  m.getBulk<Vertex>();
    if(v != NULL) {
      v->describe();
    } else {
      std::cout << "dynamic cast failed, I got the object:" << std::endl;
      o->describe();
    }
  }

private:
  VerboseObject* bulk;
};
#include <boost/python.hpp>
#include "python/bugDynamicCastSimplified.h"

using namespace boost::python;
using namespace std;

BOOST_PYTHON_MODULE(bugDynamicCastPy)
{
  class_<Mesh>("mesh", init<>())
    ;

  def("performTest", &Mesh::performTest);
}
#include <boost/python.hpp>
#include "python/bugDynamicCastSimplified.h"

using namespace boost::python;
using namespace std;

BOOST_PYTHON_MODULE(bugDynamicCast2Py)
{
  def("performTest2", &Mesh::performTest);
}

#include "bugDynamicCastSimplified.h"

#ifdef REMOVE_VIRTUAL_INHERITANCE
void Vertex::describe()
{
    std::cout << "I am a Vertex" << std::endl;
}
#endif
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to