18

我有一个名为 Foo 的 C++ 类。如果我遵循Cython C++ 教程,我将需要以不同的方式调用 Python 类,例如 PyFoo。但是我真的也需要调用 Python 类 Foo 。如何有效地做到这一点?

编辑:我正在尝试连接以前与 Boost Python 连接的现有 C++ 库。出于不同的原因,我想改为测试 Cython。由于使用 Boost:Python Python 类的名称与 C++ 中的名称相同,因此我想继续使用此命名约定。以不同的方式调用类并不是 Python (CPython) 的要求,但它似乎是 Cython 强加的,至少在本教程中是这样。

我当然可以使用纯 python 模块来定义一个调用 PyFoo 的 Foo 类,但这看起来既无聊又低效。

4

2 回答 2

24

有两种方法可以处理这个问题。

  1. 用备用名称声明 C++ 类;原始名称必须用双引号指定:

    cdef extern from "defs.h" namespace "myns":
        cdef cppclass CMyClass "myns::MyClass":
            ...
    

    然后您可以使用MyClass您的 python 类并将 C++ 声明称为CMyClass.

    请注意,原始名称必须明确包含命名空间(如果它是命名空间)。Cython 模板参数(如果存在)应该在备用名称声明之后。

  2. 在一个单独的文件中声明您的 C++ 类,该.pxd文件的名称与您的.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
    
于 2012-04-12T09:50:12.773 回答
3

这是一个展示 Nikita 方法的完整示例:

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()
于 2014-06-18T19:48:52.397 回答