Search code examples
c++pythoninheritanceboostboost-python

How do I split an inheritance relationship across separate Boost.Python modules?


I'm trying to separate my Boost.Python bindings into multiple modules. I am having a problem during module import when a class wrapped in one module inherits from a class wrapped in another module.

In this example: class Base is wrapped in module1, and class Derived (deriving from Base) is wrapped in module2. The error I get while trying to import module2 is "RuntimeError: extension class wrapper for base class class Base has not been created yet".

module1.h:

#ifndef MODULE1_H
#define MODULE1_H

#include <string>

class Base
{
public:
    virtual ~Base() {}

    virtual std::string foo() const { return "Base"; }
};

#endif // MODULE1_H

module1.cpp:

#include <boost/python.hpp>
#include "module1.h"

BOOST_PYTHON_MODULE(module1)
{
    using namespace boost::python;
    class_<Base, boost::noncopyable>("Base")
        .def("foo", &Base::foo)
        ;
}

module2.h:

#ifndef MODULE2_H
#define MODULE2_H

#include <string>
#include "module1.h"

class Derived : public Base
{
public:
    Derived() {}
    virtual ~Derived() {}

    virtual std::string foo() const { return "Derived"; }
};

#endif // MODULE2_H

module2.cpp:

#include <boost/python.hpp>
#include "module2.h"

BOOST_PYTHON_MODULE(module2)
{
    using namespace boost::python;
    class_<Derived, bases<Base>, boost::noncopyable>("Derived")
        .def("foo", &Derived::foo)
        ;
}

runner.py:

import module1
import module2

d = module2.Derived()
print(d.foo())

Solution

  • I solved this by building the Boost.Python library as a DLL. Previously I had been building Boost.Python as a static library. Because this was statically linked into each of the extension module DLLs, each module had their own copy of the Boost.Python type registry. Linking against a Boost.Python shared library resulted in a single type registry being shared by the two modules.

    b2.exe link=shared --with-python