我有一个名为Foo的C ++类。如果我遵循Cython C++ tutorial,我将需要以不同方式调用Python类,例如PyFoo。 但是我真的需要调用Python类Foo。如何有效地做到这一点?
编辑:我正在尝试连接以前与Boost Python接口的现有C ++库。出于不同的原因,我想测试Cython。 因为使用Boost:使用与C ++相同的名称调用Python Python类,我想继续使用这个命名约定。以不同方式调用类不是Python(CPython)的要求,但它似乎是由Cython强加的,至少在教程中是这样。
我当然可以使用纯python模块来定义一个调用PyFoo的Foo类,但这看起来既乏味又低效。
答案 0 :(得分:19)
有两种方法可以解决这个问题。
使用备用名称声明C ++类;原始名称必须用双引号指定:
cdef extern from "defs.h" namespace "myns":
cdef cppclass CMyClass "myns::MyClass":
...
然后,您可以将MyClass
用于您的python类,并将C ++声明称为CMyClass
。
请注意,原始名称必须明确包含命名空间(如果它是命名空间)。 Cython模板参数(如果存在)应该在备用名称声明之后。
在单独的.pxd
文件中声明您的C ++类,其名称与.pyx
文件的名称不同,然后使用cimport
导入它们。
在cpp_defs.pxd:
cdef extern from "defs.h" namespace "myns":
cdef cppclass MyClass:
...
在py_wrapper.pyx中:
cimport cpp_defs as cpp
cdef class MyClass:
cpp.MyClass *_obj
答案 1 :(得分:3)
以下是展示尼基塔方法的完整示例:
cdef extern from "floorplan_geometry.h" namespace "flyby::localize":
cdef cppclass CFloorplan "flyby::localize::Floorplan":
int xmin()
cdef class Floorplan:
cdef CFloorplan* obj_
def __cinit__(self):
self.obj_ = new CFloorplan()
def __dealloc__(self):
del self.obj_
def xmin(self):
return self.obj_.xmin()