boost python explicit typecast needed
boost-python, c++
Solution
When it comes to `boost::shared_ptr`, Boost.Python generally provides the desired functionality. In this particular case, there is no need to explicitly provide custom `to_python` converters as long as the module declaration defines that `Base` is held by `boost::shared_ptr<Base>`, and Boost.Python is told that `A` inherits from `Base`.
BOOST_PYTHON_MODULE(example) {
using namespace boost::python;
class_<Base, boost::shared_ptr<Base>,
boost::noncopyable>("Base", no_init);
class_<A, bases<Base>,
boost::noncopyable>("A", no_init);
def("factory", &factory);
def("consumer", &consumer);
}
Boost.Python does not currently support custom lvalue converters, as it requires changes to the core library. Therefore, the `consumer` function either needs accept the `boost:shared_ptr<A>` by value or by const-reference. Either of the following signatures should work:
void consumer(boost::shared_ptr<A> a)
void consumer(const boost::shared_ptr<A>& a)
Here is a complete example:
#include <boost/python.hpp>
#include <boost/make_shared.hpp>
class Base
{
public:
virtual ~Base() {}
};
class A
: public Base
{
public:
A(int value) : value_(value) {}
int value() { return value_; };
private:
int value_;
};
boost::shared_ptr<Base> factory()
{
return boost::make_shared<A>(42);
}
void consumer(const boost::shared_ptr<A>& a)
{
std::cout << "The value of object is " << a->value() << std::endl;
}
BOOST_PYTHON_MODULE(example) {
using namespace boost::python;
class_<Base, boost::shared_ptr<Base>,
boost::noncopyable>("Base", no_init);
class_<A, bases<Base>,
boost::noncopyable>("A", no_init);
def("factory", &factory);
def("consumer", &consumer);
}
And the usage:
>>> from example import *
>>> x = factory()
>>> type(x)
<class 'example.A'>
>>> consumer(x)
The value of object is 42
>>>
Since the module declaration specified that `Base` was a base-class for `A`, Boost.Python was able to resolves the type returned from `factory()` to `example.A`.
Problem
I have hybrid system (c++, boost python). In my c++ code there is very simple hierarchy ``` class Base{...} class A : public Base{...} class B : public Base{...} ``` 2 more business (on c++) methods ``` smart_ptr<Base> factory() //this produce instances of A and B void consumer(smart_ptr<A>& a) //this consumes instance of A ``` In python code I create instance of A with the `factory` and try to call consumer method: ``` v = factory() #I'm pretty sure that it is A instance consumer(v) ``` Absolutely reasonable I've got exception: Python argument types in consumer(Base) did not match to C++ signature: consumer(class A{lvalue}) It happens because no way how to tell Boost that some conversion efforts should be there. Is there some way how to specify dynamic casting behavior? Thank you in advance.