我正在尝试使用 Boost.Python 公开这个 C++ 类:
class VAlgorithm {
public:
VAlgorithm(const char *name);
virtual ~VAlgorithm();
virtual bool Initialize() = 0;
virtual bool Process() = 0;
virtual bool Finalize() = 0;
virtual const char *GetName() const; // Default implementation in cpp file
}
我的最终目标是在 python shell 中将 VALgorithm 的子级定义为 python 类。按照这个例子,我定义了一个回调类:
class VAlgorithm_callback: public VAlgorithm {
public:
VAlgorithm_callback(PyObject *p, const char *name) :
self(p), VAlgorithm(name) {
}
const char * GetName() const {
return call_method<const char *>(self, "GetName");
}
static const char * GetName_default(const VAlgorithm& self_) {
return self_.VAlgorithm::GetName();
}
private:
PyObject *self;
};
现在我只公开类本身和 GetName() 方法。由于它是一个虚拟类,我将这段代码放在 BOOST_PYTHON_MODULE 中:
class_<VAlgorithm, VAlgorithm_callback, boost::noncopyable>("VAlgorithm", no_init) //
.def("GetName", &VAlgorithm_callback::GetName_default); //
我可以编译它并将模块加载到 python shell 中。然后我尝试定义一个子类并调用 C++ 代码中定义的 GetName() 默认实现:
>>> class ConcAlg1(VAlgorithm):
... pass
...
>>> c1 = ConcAlg1("c1")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: This class cannot be instantiated from Python
>>> class ConcAlg2(VAlgorithm):
... def __init__(self, name):
... pass
...
>>> c2 = ConcAlg2("c2")
>>> c2.GetName()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
VAlgorithm.GetName(ConcAlg2)
did not match C++ signature:
GetName(VAlgorithm)
>>> class ConcAlg3(VAlgorithm):
... def __init__(self, name):
... super(ConcAlg3, self).__init__(self, name)
...
>>> c3 = ConcAlg3("c3")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
RuntimeError: This class cannot be instantiated from Python
我不是专家(只是第一次遇到这些问题),但在我看来,ConcAlg1 和 ConcAlg3 尝试实例化一个 VAlgorithm 对象并由于公开 VAlgorithm 时使用的 no_init 参数而失败(我不能省略它或代码不会编译),并且 ConcAlg2 不能调用 GetName() ,因为它不被识别为 VAlgorithm 的子代。我一定是做错了什么,但我不知道是什么(我是 Boost.Python 和扩展的新手)。谁能帮帮我吗?谢谢