我有现成的C++代码来定义一些我需要使用的类,但我需要能够将这些类发送到Python代码。具体来说,我需要用C++创建类实例,创建Python对象来充当这些C++对象的包装,然后将这些Python对象传递给Python代码进行处理。这只是一个更大的C++程序中的一部分,所以最终需要使用C/Python API在C++中完成。Cython扩展类:如何在自动生成的C结构中公开方法?
为了让我的生活更轻松,我使用了Cython来定义扩展类(cdef类),它充当我的C++对象的Python包装器。我使用的典型格式是cdef类包含一个指向C++类的指针,该指针在创建cdef类实例时被初始化。由于我也希望能够替换指针,如果我有一个现有的C++对象来包装,我已经添加了方法到我的cdef类到C++对象并取其指针。我的其他cdef类在Cython中成功使用accept()
方法,例如,当一个对象拥有另一个对象时。
下面是我用Cython代码示例:
MyCPlus.pxd
cdef extern from "MyCPlus.h" namespace "mynamespace":
cdef cppclass MyCPlus_Class:
MyCPlus_Class() except +
PyModule.pyx
cimport MyCPlus
from libcpp cimport bool
cdef class Py_Class [object Py_Class, type PyType_Class]:
cdef MyCPlus.MyCPlus_Class* thisptr
cdef bool owned
cdef void accept(self, MyCPlus.MyCPlus_Class &indata):
if self.owned:
del self.thisptr
self.thisptr = &indata
self.owned = False
def __cinit__(self):
self.thisptr = new MyCPlus.MyCPlus_Class()
self.owned = True
def __dealloc__(self):
if self.owned:
del self.thisptr
问题是当我尝试从C访问accept()
方法++。我尝试在我的cdef类和accept()
方法上使用public
和api
关键字,但我无法弄清楚如何在Cython的自动生成的.h
文件中的C结构中公开此方法。不管我怎么努力,在C结构是这样的:
PyModule.h
(通过用Cython自动生成)
struct Py_Class {
PyObject_HEAD
struct __pyx_vtabstruct_11PyModule_Py_Class *__pyx_vtab;
mynamespace::MyCPlus_Class *thisptr;
bool owned;
};
我也试着键入self
输入为Py_Class
,我甚至试过前置声明Py_Class
与public
和api
关键字。我也尝试使accept()
成为一种静态方法。我已经尝试过的任何方法都可以公开accept()
方法,以便我可以在C++中使用它。我尝试通过__pyx_vtab
尝试访问它,但是我收到了一个编译器错误,“不完整类型的无效使用”。我搜索了很多,但没有看到解决方案。谁能帮我?谢谢,麻烦您了!
'static void __pyx_f_8PyModule_8Py_Class_accept(struct __pyx_obj_8PyModule_Py_Class * __ pyx_v_self,mynamespace :: MyCPlus_Class&__ pyx_v_indata);/* proto * /'看起来似乎是可以使用的东西。 – DavidW
@DavidW,这可能会工作一段时间,但我真的在寻找一种解决方案,告诉Cython将此方法放入我的API中。上面引用的行深埋在自动生成的'.cpp'文件中,并且可能会意外更改。我需要一个更可维护的解决方案。不过,谢谢你的尝试。 –
你可以尝试的另一件事是在* pxd和pyx文件中声明'accept()' - 如果你把它作为一个完全声明的类方法(而不仅仅是一个'extern'方法原型被暴露),并且Cython生成一个相应命名的可访问方法,它会是你的调用或覆盖 – fish2000