我很感激帮助使boost-python使用我为抽象基类定义的包装类来包装派生类。
我有一个抽象的C ++基类baz
,派生类foo
(未公开)和bar
(公开给python)。有一个工厂函数返回boost::shared_ptr<baz>
指向foo
的实例,在这里我希望工厂的boost::shared_ptr<baz>
包含在baz_callback
中。我还想覆盖python中的pure
,它似乎适用于基类baz
(在mumble
python类中重写),但不适用于派生类{{1} }(在bar
中重写)。
为了说明,我从python wiki扩展了example,见下文。所有打印输出应该有一个1作为第二个数字,来自jungle
,但只有baz_callback::pure
版本才能正确。对于mumble
,忽略jungle
的python版本,而使用C ++版本。
档案pure
:
override_shared.cc
档案#include <boost/python/class.hpp>
#include <boost/python/module_init.hpp>
#include <boost/python/def.hpp>
#include <boost/python/call_method.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>
#include <boost/python/register_ptr_to_python.hpp>
#include <boost/python/pure_virtual.hpp>
using namespace boost::python;
struct baz {
virtual int pure(int) = 0;
int calls_pure(int x) { return pure(x) + 1000; }
};
struct foo : baz {
int pure(int i) { return i+10; };
};
struct bar : baz {
int pure(int i) { return i+30; };
};
struct baz_callback : baz {
baz_callback(PyObject *p) : self(p) {}
int pure(int x) { return 100 + call_method<int>(self, "pure", x); }
PyObject *self;
};
boost::shared_ptr<baz> make_foo()
{
return boost::shared_ptr<foo>(new foo());
}
boost::shared_ptr<baz> make_bar()
{
return boost::shared_ptr<bar>(new bar());
}
BOOST_PYTHON_MODULE_INIT(liboverride_shared)
{
class_<baz, boost::shared_ptr<baz_callback>, boost::noncopyable>("baz")
.def("pure", pure_virtual(&baz::pure))
.def("calls_pure", &baz::calls_pure);
class_<bar, bases<baz> >("bar");
def("make_foo", make_foo);
def("make_bar", make_bar);
// I suspect the problem lies here:
register_ptr_to_python< boost::shared_ptr<baz> >();
}
:
override_shared.py
档案from liboverride_shared import *
f = make_foo()
class mumble(baz):
def pure(self, x): return x + 20
m = mumble()
class jungle(bar):
def pure(self, x): return x + 40
j = jungle()
def check(name, bar, i, expected):
actual = bar.calls_pure(i)
msg = "ok" if actual == expected else ("bad, expected %d" % expected)
print (name, actual, "--", msg)
check("foo", f, 1, 1111)
check("mumble", m, 2, 1122)
check("jungle", j, 4, 1144)
:
CMakeLists.txt