Boost logo

Boost Users :

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


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
2. Clone a python class instance and return a shared_ptr to the new

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

     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
     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"; }

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

     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")(); }

   def("whoiam", &whoiam);

   class_<BaseWrapper, shared_ptr<BaseWrapper>, noncopyable>("Base",
     .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
class DerivedB(Base):
     def __init__(self, data):
         self.__data = data

     def create(data):
         return DerivedB(data)

     def copy(self):
         return self

     def name(self):
         return 'derivedB'

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

Here is the result of the interpreter for both whoiam lines:
Boost.Python.ArgumentError: Python argument types in
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,

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at