0

我正在尝试包装 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},
)
4

0 回答 0