Click here to Skip to main content
15,064,915 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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!


C++
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:

C++
// append our module to the initialization table ... documentation specifies to perform this before calling Py_Initialize()
PyImport_AppendInittab( "TestPythonDLL", &PyInit_TestPythonDLL );

//Initialize the interpreter
Py_Initialize();

//Get handles to the main module and top level namespace of the interpreter
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");

//Import our module so the script doesn't need to
object TestPythonDLL_module( (handle<>(PyImport_ImportModule("TestPythonDLL"))) );

//Add our module to the main namespace
main_namespace["TestPythonDLL"] = TestPythonDLL_module;

//Initialize Test Class
Container container;

//Populate the module with our data
scope(TestPythonDLL_module).attr("Container") = ptr(&container);


The script is pretty simple, but is failing.

PHP
# 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.
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900