|
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