我正在使用Boost Python为C ++中的某些类提供python接口。 我发现这种情况我不确定如何解决:
我有一个具有此成员函数的类:
virtual void visit(const ReportClass r) = 0;
virtual void visit(const unsigned int category) = 0;
virtual void visit(const char* type) = 0;
virtual void visit(const char* name, const unsigned int id, const char &value ) = 0;
virtual void visit(const char* name, const unsigned int id, const unsigned short &value ) = 0;
virtual void visit(const char* name, const unsigned int id, const unsigned int &value ) = 0;
virtual void visit(const char* name, const unsigned int id, const MaskedAddr &value ) = 0;
virtual void visit(const char* name, const unsigned int id, const unsigned long long &value ) = 0;
我对如何实现python-boost部分感到有点迷失,我已经看到了如何继续使用虚函数和重载函数,但我不知道如何将两者结合起来。
顺便说一句,我在示例中看到返回int(例如)的虚函数应该以这种方式实现:
int f()
{
return this->get_override("f")();
}
在我的情况下,他们不会返回任何内容,我想我应该以这种方式实现它们:
void f()
{
this->get_override("f")();
}
这是对的吗?
提前致谢
答案 0 :(得分:1)
让我们先回答一个简单的问题:你总是可以“返回this-> get_override(”f“)();”,即使返回类型为void。实际上,在这样的包装器代码中,我发现即使是更好的选择,因为如果包装函数突然返回某些内容,则会出现编译错误!
现在这个难题:如何在这里混合虚拟和重载函数。我会使用模板方法模式来规避这个问题。我们的想法是简单地提供一个调用私有虚函数的公共非虚函数。 (可选)您可以对虚拟文件进行保护,以允许扩展而不是覆盖。此外,在非虚拟的情况下,您可以验证派生类必须满足的前/后条件或验证参数(例如断言(名称);)。
答案 1 :(得分:1)
如果我正确理解了您的问题,您希望将纯虚拟(重载)方法绑定到Python,这样它们就可以从python 重载。您拥有的already found教程部分解释了这一点。在您的特定情况下,C ++和Python不能与重载相互配合。虽然C ++允许,但Python禁止。 Python中不能有两个名为f
的方法。我们要做的是分散 python调用,这样用户就可以实现Python的覆盖。
我会写一个较小的例子,但你可以从中抽象出来。
让我们从C ++管道开始。您的C ++绑定应如下所示:
struct BaseWrap : Base, boost::python::wrapper<Base> {
int f() {
return this->get_override("__f1__")();
}
int f(int i) {
return this->get_override("__f2__")()
}
int f(const char* s) {
return this->get_override("__f3__")()
}
int f(const char* s, double d) {
return this->get_override("__f4__")()
}
};
//your module code will look like this
BOOST_PYTHON_MODULE(example) {
using namespace boost::python;
class_<BaseWrap, boost::noncopyable>("Base")
.def("f", pure_virtual(((int)(Base::*)())&Base::f))
.def("f", pure_virtual(((int)(Base::*)(int))&Base::f))
.def("f", pure_virtual(((int)(Base::*)(const char*))&Base::f))
.def("f", pure_virtual(((int)(Base::*)(const char*, double))&Base::f))
;
}
我们做了什么?当代码的Python端调用f(<parameters>)
时,我们将解析为正确的重载方法。然后,此方法将调用Python的__f1__
,__f2__
等,其中方法的内容实际上是从Python编写的。
要完成绑定,在Python中,您必须继承example.Base
并实施__f1__
,__f2__
,__f3__
和__f4__
:
class Base(example.Base):
"""Throw here the documentation of Base - don't bother about the C++ stuff"""
def __init__(self,...):
pass
def __f1__(self):
"""Implementation of Base::f()"""
pass
def __f2__(self):
"""Implementation of Base::f(int)"""
pass
def __f3__(self):
"""Implementation of Base::f(const char*)"""
pass
def __f4__(self):
"""Implementation of Base::f(const char*, double)"""
pass