Boost logo

Boost Users :

From: Andreas (pirx_at_[hidden])
Date: 2005-01-24 16:50:07


hello,

I have a problem with conversion of python class instances to shared_ptr
inside python.
I defined an abstract base class in c++ that is used in c++ and in
embedded python. Only shared_ptr to the concrete instances should be
useable. Thus the concrete classes have hidden ctor's. They must provide
a factory method for creating. Copying of an object must be done using a
clone method.
In detail there are two problems to be done in python:
1. Create a shared_ptr to a new class instance by using a class factory
    method
2. Clone a python class instance and return a shared_ptr to the new
    instance

The example code:
//in c++
class Base
{
   public:
     virtual ~Base() {}
     virtual shared_ptr<Base> clone() const = 0;
     virtual std::string name() const = 0;

   protected:
     Base() {}
};

void whoiam(shared_ptr<Base> pBase) { std::cout << pBase->name(); }

//for better explanation of the context described above an concrete
//class in c++
class DerivedA : public Base
{
   public:
     static shared_ptr<DerivedA> create(int n, bool b)
     { return shared_ptr<DerivedA>(new DerivedA(n, b)); }

     virtual shared_ptr<Base> clone() const
     { return shared_ptr<DerivedA>(new DerivedA(*this)); }

     virtual std::string name() const { return "derivedA"; }

   protected:
     DerivedA(int n, bool b) : _n(n), _b(b) {}
     DerivedA(const DerivedA& other) : _n(other._n) {}

   private:
     int _n;
     bool _b;
};

//wrapping base
struct BaseWrapper : public Base, wrapper<Base>
{
   shared_ptr<Base> clone() const {return this->get_override("clone")();}
   std::string name() const { return this->get_override("name")(); }
};

//export
BOOST_PYTHON_MODULE(test)
{
   def("whoiam", &whoiam);

   class_<BaseWrapper, shared_ptr<BaseWrapper>, noncopyable>("Base",
     no_init)
     .def("clone", pure_virtual(&Base::clone))
     .def("name", pure_virtual(&Base::name))
   ;
}

//in python
from test import *

//an concrete class in python with the problematic create and copy
//methods
class DerivedB(Base):
     def __init__(self, data):
         self.__data = data

     @staticmethod
     def create(data):
         return DerivedB(data)

     def copy(self):
         return self

     def name(self):
         return 'derivedB'

b = DerivedB.create('somestring')
whoiam(b)
bCopied = b.copy()
whoiam(bCopied)

Here is the result of the interpreter for both whoiam lines:
whoiam(b)
Boost.Python.ArgumentError: Python argument types in
whoiam(DerivedB)
did not match C++ signature:
whoiam(class boost::shared_ptr<class Base>)

How can i define/register an converter which does such a conversion?
(I'm using Boost 1.32.0, MSVC7.1 and Python 2.4)

Thanks a lot for any help,
andreas


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net