这是一个抽象基类和一个具体的子类,我想通过Cython向Python公开:
class NodeDistance {
protected:
const Graph& G;
public:
NodeDistance(const Graph& G);
virtual ~NodeDistance();
virtual void preprocess() = 0;
virtual double distance(node u, node v) = 0;
};
class NeighborhoodDistance: public NetworKit::NodeDistance {
public:
NeighborhoodDistance(const Graph& G);
virtual ~NeighborhoodDistance();
virtual void preprocess();
virtual double distance(node u, node v);
};
这是我第一次尝试声明Cython类的接口。为了避免在cppclass
es和Python包装器类之间发生命名冲突,我将每个Class
声明为_Class
,后跟其正确的名称"Namespace::Class"
。
cdef extern from "../cpp/distmeasures/NodeDistance.h":
cdef cppclass _NodeDistance "NetworKit::NodeDistance":
_NodeDistance(_Graph G) except +
void preprocess() except +
double distance(node, node) except +
cdef extern from "../cpp/distmeasures/NeighborhoodDistance.h":
cdef cppclass _NeighborhoodDistance(_NodeDistance) "NetworKit::NeighborhoodDistance":
_NeighborhoodDistance(_Graph G) except +
void preprocess() except +
double distance(node, node) except +
但是现在我在尝试表达_NeighborhoodDistance
是_NodeDistance
的子类时遇到语法错误。我做错了什么?
Error compiling Cython file:
------------------------------------------------------------
...
void preprocess() except +
double distance(node, node) except +
cdef extern from "../cpp/distmeasures/NeighborhoodDistance.h":
cdef cppclass _NeighborhoodDistance(_NodeDistance) "NetworKit::NeighborhoodDistance":
^
------------------------------------------------------------
_NetworKit.pyx:1698:52: Syntax error in C++ class definition
答案 0 :(得分:2)
我认为你甚至不能在Cython 0.20.1中表达基类和重命名的组合。您可以不重命名类并在cdef extern from
:
# C++ classes shown at the end
cdef extern from "example.hpp" namespace "example":
cdef cppclass Base:
void some_method() except +
cdef cppclass Derived(Base):
void some_method() except +
...或者不指定继承:
cdef extern from "example.hpp" namespace "example":
cdef cppclass Base "example::Base":
void some_method() except +
cdef cppclass Derived "example::Derived":
void some_method() except +
无论哪种方式,Cython似乎都不完全理解C ++继承,你需要一个显式的强制转换:
def test():
cdef Derived d
cdef Base *p = <Base *>&d
p.some_method()
这很难看,因为演员有效地关闭了C ++中的类型检查,但是要小心它可以安全使用。 (在其他情况下,Cython的类型检查需要在C / C ++中不需要的强制转换,这是非常不幸的。)
供参考,以下是我使用的课程:
// example.hpp
#include <cstdio>
namespace example {
struct Base {
virtual void some_method() = 0;
virtual ~Base() = 0;
};
struct Derived {
virtual void some_method()
{
std::puts("Hello!");
}
~Derived()
{
}
};
}