我正在尝试使用 cinit 来实现cdef类,它必须使用cdef结构指针。
C标题
typedef struct foo *FOO;
PXD文件:
extern ...:
cdef struct foo
ctypedef foo *FOO
PYX文件:
cdef class ClassX(object):
def __cinit__(self, FOO arg):
...
Cython编译器说“无法将Python对象参数转换为'FOO'类型”。有什么问题以及如何将struct指针传递给 cinit ?
答案 0 :(得分:1)
看起来我发现了类似的问题:how to cython class function's parameter accept c++ struct。简短回答:无法将C-struct传递给Python(def)函数。我必须将一个结构包装到Python对象中。
答案 1 :(得分:0)
这里有一些我设法为我的案例解决它的方法,这些方法非常具体。
方法 1 - 将指针转换为 uint64 数字(有点脏) 您必须确保在复制之前没有删除引用,但首先将您的结构指针转换为一个无符号的 64 位数字,然后转换并可能 deref 回您的对象。像这样
from cython.operator cimport dereference as deref
ctypedef unsigned long long uint64_t
...
cdef class SomeClass(object):
cdef FooStruct foo
def __cinit__(self, uint64_t arg):
self.foo = deref(<FooStruct*> arg) # preferably copy over keeping pointer
然后构建它
cdef FooStruct yourfoo = ... # your struct
cdef SomeClass res
res = SomeClass(<uint64_t> &yourfoo)
这不是最漂亮的解决方案,但它适用于特定情况。
方法 2 - 相同的 PYX 文件分配功能(首选)
我发现此方法仅适用于同一个 PYX 文件中的对象引用。因此,如果您使用复制数据的 setter 函数定义 cdef class
,该函数不会暴露给 python,那么您可以更新内部结构。
cdef class SomeClass(object):
cdef FooStruct foo
def __cinit__(self):
...
cdef void _set(self, FooStruct &data):
self.foo = data # copy
现在构造它的两行
cdef FooStruct yourfoo = ... # your struct
cdef SomeClass res
res = SomeClass()
res._set(yourfoo)