[C++-sig] problem with boost::python::extract of c++ pointers from objects with multiple inheritance

Carsten Harms CarstenHarms9368 at gmx.de
Wed Jun 25 11:17:04 CEST 2008


Here is a small app which reproduces the behaviour:
--------------------------------------------------
#define BOOST_PYTHON_STATIC_LIB
#include <boost/python.hpp>
#include <iostream>
#include "conio.h"

using namespace boost::python;

class Base1
{
public:
    virtual ~Base1() {}
    virtual void func1 () = 0;
};

class Base1Wrap: public Base1, public wrapper<Base1>
{
public:
    virtual ~Base1Wrap() {}
    void func1 () {    this->get_override("func1")(); }
};


class Base2
{
public:
    virtual ~Base2() {}
    virtual void func2 () = 0;
};

class Base2Wrap: public Base2, public wrapper<Base2>
{
public:
    virtual ~Base2Wrap() {}
    void func2 () {    this->get_override("func2")(); }
};



void extractBase1( boost::python::object& obj)
{
    Base1* ex1 = extract<Base1*>(obj) BOOST_EXTRACT_WORKAROUND;
    Base1& ex2 = extract<Base1&>(obj) BOOST_EXTRACT_WORKAROUND;

    ex1->func1();
    ex2.func1();
}

void extractBase2( boost::python::object& obj)
{
    Base2* ex1 = extract<Base2*>(obj) BOOST_EXTRACT_WORKAROUND;
    Base2& ex2 = extract<Base2&>(obj) BOOST_EXTRACT_WORKAROUND;

    ex1->func2();
    ex2.func2();
}


BOOST_PYTHON_MODULE(Test_ext)
{
    class_<Base1Wrap, boost::noncopyable>("Base1")
        .def("func1", pure_virtual(&Base1::func1))
        ;

    class_<Base2Wrap, boost::noncopyable>("Base2")
        .def("func2", pure_virtual(&Base2::func2))
        ;

    def("extractBase1", extractBase1);
    def("extractBase2", extractBase2);
}


int main(int, char **)
{
  try
  {
      Py_Initialize();
      
      initTest_ext();

      object main = import("__main__");
      object dictionary(main.attr("__dict__"));

      object result = exec_file("test.py", dictionary, dictionary );
      
      //Py_Finalize();
  }
  catch (error_already_set)
  {
      PyErr_Print();
  }

  while(!kbhit());

  return 0;
}
--------------------------------------------------
python script:
--------------------------------------------------

from Test_ext import *

class class1(Base1):
    def func1(self):
        print "func1 called!"
       
class class2(Base2):
    def func2(self):
        print "func2 called!"

class both1(Base1, Base2):
    def func1(self):
        print "func1 called!"
    def func2(self):
        print "func2 called!"
       
class both2(Base2, Base1):
    def func1(self):
        print "func1 called!"
    def func2(self):
        print "func2 called!"

#################################
object1 = class1()
object2 = class2()

extractBase1(object1)
extractBase2(object2)


object3 = both1()

extractBase1(object3)
extractBase2(object3)    # doesn't work

object4 = both2()

extractBase1(object4)    # doesn't work
extractBase2(object4)



More information about the Cplusplus-sig mailing list