我正在尝试包装 C++ Base 和 Derived 类,而 Base 是一个抽象类。(我已对此进行了编辑以制作此示例 SSCCE)。Base 类定义了接口,我不想在 Derived Python 类中重复它们(不确定是否可能)。但是我不知道如何告诉 Cython,Derived 是从 Base 派生的。我尝试了几种方法,但都没有成功。
#include <string>
class Base {
std::string name_;
public:
Base (const std::string& name): name_(name) {}
std::string name() const { return name_; }
void setName(const std::string& name) { name_ = name; }
virtual double length() const = 0;
virtual ~Base() {}
};
class Derived: public Base {
double len_;
public:
Derived(const std::string& name, double len) : Base(name), len_(len){ }
virtual double length() const { return len_; }
void setLength(double len) { len_ = len; }
};
我正在尝试使用 Cython 包装这两个类:
from libcpp.string cimport string
cdef extern from "base.h":
cdef cppclass c_Base "Base":
string name_
string name()
void setName(const string& name)
cdef extern from "base.h":
ctypedef struct c_Derived "Derived":
double len_
double length()
void setLength(double v)
c_Derived *new_Derived "new Derived" (const string& name, double len)
void del_Derived "delete" (c_Derived *p)
from tlib cimport c_Derived
cdef class Base:
cdef c_Base *thisptr
def __cinit__(self, const string& name):
pass
property name:
def __get__(self): return self.thisptr.name()
def __set__(self, const string& v): self.thisptr.setName(v)
cdef class Derived:
cdef c_Derived *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self, const string& name, double len):
self.thisptr = new_Derived(name, len)
def __dealloc__(self):
del_Derived(self.thisptr)
property length:
def __get__(self): return self.thisptr.length()
def __set__(self, double v): self.thisptr.setLength(v)
setup.py 是这样的:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
name = 'pytlib',
ext_modules=[
Extension("tlib",
sources=["tlib.pyx"],
include_dirs=["."],
language="c++"),
],
cmdclass = {'build_ext': build_ext},
)