This seems like it should be trivial, but I'm having problems getting started with Boost Python. I want to make a little demo to work out some issues. The main problem is that I need to have a class with a member function return a shared_ptr to a base type. That base type will almost always be some other type, so I'll want to use the derived type in Python.
While the Internet is full of examples and questions, I can't seem to find this specific scenario in a complete, working form.
My understanding is that since Python is duck typed, it should just be the proper derived type. However, when I run my test script, my returned type is showing up as the base class type within Python. Any help would be appreciated!
namespace PythonTestClass
{
class Base
{
public:
Base(void);
~Base(void);
};
class Derived : public Base
{
public:
Derived(void) {};
~Derived(void){};
};
class Container
{
public:
Container(void) : mine(new Derived()) {};
~Container(void){};
boost::shared_ptr<Base> getBase() { return mine; }
private:
boost::shared_ptr<Base> mine;
};
BOOST_PYTHON_MODULE(TestPythonDLL)
{
boost::python::class_<Base>("Base", boost::python::no_init);
boost::python::register_ptr_to_python<boost::shared_ptr<Base>>();
boost::python::class_<Derived, boost::python::bases<Base>>("Derived", boost::python::no_init)
.def("testCall", &Derived::testCall)
;
boost::python::register_ptr_to_python<boost::shared_ptr<Derived>>();
boost::python::class_<Container>("Container", boost::python::no_init)
.def("getBase", &Container::getBase)
;
boost::python::register_ptr_to_python<boost::shared_ptr<Container>>();
boost::python::implicitly_convertible<boost::shared_ptr<Derived>, boost::shared_ptr<Base>>();
}
}
I'm setting up Boost Python as follows:
PyImport_AppendInittab( "TestPythonDLL", &PyInit_TestPythonDLL );
Py_Initialize();
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
object TestPythonDLL_module( (handle<>(PyImport_ImportModule("TestPythonDLL"))) );
main_namespace["TestPythonDLL"] = TestPythonDLL_module;
Container container;
scope(TestPythonDLL_module).attr("Container") = ptr(&container);
The script is pretty simple, but is failing.
# Test Script File
classptr = TestPythonDLL.Container.getBase()
classptr.incrementCounter()
print(type(classptr))
classptr.testCall()
Here, type(classptr) looks like a Base, but I think/want this to be a Derived.