如何使用 Cython 保持 C++ 类名不被修改?
Posted
技术标签:
【中文标题】如何使用 Cython 保持 C++ 类名不被修改?【英文标题】:How to keep a C++ class name unmodified with Cython? 【发布时间】:2012-04-11 22:12:43 【问题描述】:我有一个名为 Foo 的 C++ 类。如果我遵循Cython C++ tutorial,我将需要以不同的方式调用 Python 类,例如 PyFoo。 但是我真的也需要调用 Python 类 Foo 。如何有效地做到这一点?
编辑:我正在尝试连接以前与 Boost Python 连接的现有 C++ 库。出于不同的原因,我想改为测试 Cython。 由于使用 Boost:Python Python 类的名称与 C++ 中的名称相同,因此我想继续使用此命名约定。以不同的方式调用类并不是 Python (CPython) 的要求,但它似乎是 Cython 强加的,至少在本教程中是这样。
我当然可以使用纯 python 模块来定义一个调用 PyFoo 的 Foo 类,但这看起来既无聊又低效。
【问题讨论】:
为什么不把 C++ 类改成 CppFoo 呢? 因为那样我还需要调用 Python 类 CppFoo... 是什么让你觉得PyFoo
这个名字很特别?据我所知,唯一真正的要求是名称不同,唯一的原因是您将在 Python 类型的实现中引用 C++ 类型。
我编辑了我的问题,以便更清楚地了解我的目标。
为什么不拥有一个与 Cython 一起工作的模块,这样即使你对命名不满意,它也能正常工作,然后制作另一个作为外观的模块,除了类似'from _CppFoo 导入 *; Foo = PyFoo'
【参考方案1】:
有两种方法可以解决这个问题。
用替代名称声明 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
【讨论】:
对我来说,第二个选项抱怨在py_wrapper.pyx
中重新定义MyClass
,尽管看起来cpp.MyClass
确实应该被视为一个单独的东西。第一个选项对我来说很好,尽管 namespace "myns"
必须在上一行,因为 cdef extern from "defs.h" namespace "myns":
或 cython 抱怨语法错误。 [使用 Cython 版本 0.20.1。]
函数有没有办法做到这一点?
函数有什么问题?文本覆盖(双引号)适用于所有 cdef 对象:类、函数、结构、typedef 等。将声明移动到单独的 .pxd(更自然的命名空间解决方案)也适用于所有对象。
@Mike 对于第二个选项,pyd 和 pyx 文件必须具有不同的名称。【参考方案2】:
这是一个完整的例子,展示了 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()
【讨论】:
以上是关于如何使用 Cython 保持 C++ 类名不被修改?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Cython 时如何将一个 C++ 类(引用)传递给另一个?
如何在 Cython 中将 Python 对象转换为 C++ 类型