【发布时间】:2016-01-20 17:12:33
【问题描述】:
我现有的 C++ 代码定义了一些我需要使用的类,但我需要能够将这些类发送到 Python 代码。具体来说,我需要在 C++ 中创建类实例,创建 Python 对象作为这些 C++ 对象的包装器,然后将这些 Python 对象传递给 Python 代码进行处理。这只是一个更大的 C++ 程序的一部分,因此最终需要使用 C/Python API 在 C++ 中完成。
为了让我的生活更轻松,我使用 Cython 定义了扩展类(cdef 类),它们充当我的 C++ 对象的 Python 包装器。我使用的是典型格式,其中 cdef 类包含指向 C++ 类的指针,然后在创建 cdef 类实例时对其进行初始化。因为如果我有一个现有的 C++ 对象要包装,我还希望能够替换指针,我已将方法添加到我的 cdef 类到 accept() 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,我什至尝试使用public 和api 关键字前向声明Py_Class。我还尝试将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,这可能会工作一段时间,但我真的在寻找如何告诉 Cython 将此方法放入我的 API 的解决方案。您在上面引用的行深埋在自动生成的
.cpp文件中,它可能会意外更改。我需要一个更易于维护的解决方案。不过,感谢您的尝试。 -
你可以尝试的另一件事是在
pxd和pyx文件两个中声明accept()——如果你有一个完全声明的类方法(不仅仅是要公开的extern方法原型),并且 Cython 生成一个相应命名的可访问方法,您可以调用或覆盖 -
@fish2000
accept()方法不是我原来的 C++ 类的一部分(我不能添加它),所以没有理由放入pxd。我需要将它包含在我的扩展类的 C 结构中,这样我就可以为我的 C++ 对象创建一个扩展类包装器,然后我可以将其发送到 Python。这很有趣,因为 Cython 确实输入了__pyx_vtab,但这似乎仅供 Cython 使用,不适用于外部 C/C++ 代码。我认为 Cython 还没有设计成这样做。