Python 如何编写封装预分配数据的扩展类型?
我有一些已经分配和初始化的结构中的数据。 我可以保证,在这些对象的任何生存期内,数据都不会被释放。如何用Cython将其包装到Python对象中?以下内容不起作用,但我希望它能解释我的意图:Python 如何编写封装预分配数据的扩展类型?,python,c,cython,Python,C,Cython,我有一些已经分配和初始化的结构中的数据。 我可以保证,在这些对象的任何生存期内,数据都不会被释放。如何用Cython将其包装到Python对象中?以下内容不起作用,但我希望它能解释我的意图: from libc.stdlib cimport malloc ctypedef struct Point: int x int y cdef class _MyWrapper: cdef Point* foo def __cinit__(self, Point* foo
from libc.stdlib cimport malloc
ctypedef struct Point:
int x
int y
cdef class _MyWrapper:
cdef Point* foo
def __cinit__(self, Point* foo):
self.foo = foo
def create_eternal_MyWrapper(int x, int y):
cdef Point* p
p = <Point*>malloc(sizeof(Point))
p.x = x
p.y = y
return _MyWrapper(p)
来自libc.stdlib cimport malloc
ctypedef结构点:
整数x
智力
cdef类\u MyWrapper:
cdef点*foo
定义(自我,点*foo):
self.foo=foo
def create_external_MyWrapper(整数x,整数y):
cdef点*p
p=malloc(sizeof(点))
p、 x=x
p、 y=y
返回_MyWrapper(p)
在此服务器上运行cython的输出:
Error compiling Cython file:
------------------------------------------------------------
...
def create_eternal_MyWrapper(int x, int y):
cdef Point* p
p = <Point*>malloc(sizeof(Point))
p.x = x
p.y = y
return _MyWrapper(p)
^
------------------------------------------------------------
examplecy.pyx:17:23: Cannot convert 'Point *' to Python object
编译Cython文件时出错:
------------------------------------------------------------
...
def create\u永恒\u MyWrapper(int x,int y):
cdef点*p
p=malloc(sizeof(点))
p、 x=x
p、 y=y
返回_MyWrapper(p)
^
------------------------------------------------------------
pyx:17:23:无法将“点*”转换为Python对象
如前所述,和方法都使用PyObject\u调用
API函数,该函数只能接受PyObject类型的参数。因此,正如中所建议的,您应该在全局工厂方法内初始化C属性:
from libc.stdlib cimport malloc
ctypedef struct Point:
int x
int y
cdef class _MyWrapper:
cdef Point* fooless
def __init__(self, *args, **kwargs):
raise TypeError("This class cannot be instantiated from Python")
cpdef _MyWrapper create_MyWrapper(int x, int y):
cdef _MyWrapper w = _MyWrapper.__new__(_MyWrapper)
cdef Point* p
p = <Point*>malloc(sizeof(Point))
p.x = x
p.y = y
w.foo = p
# initialize all other fields explicitly
# ...
return w
来自libc.stdlib cimport malloc
ctypedef结构点:
整数x
智力
cdef类\u MyWrapper:
cdef点*愚蠢
定义初始化(self,*args,**kwargs):
raise TypeError(“无法从Python实例化此类”)
cpdef_MyWrapper create_MyWrapper(int x,int y):
cdef\u MyWrapper w=\u MyWrapper.\u新的\u(\u MyWrapper)
cdef点*p
p=malloc(sizeof(点))
p、 x=x
p、 y=y
w、 foo=p
#显式初始化所有其他字段
# ...
返回w
当然可以在\u MyWrapper
本身中创建一个专用的初始化方法,但我认为这是相当不安全的,因为在类实例化之后,用户可能会忘记调用此类方法
PS:如果有一个更简单的解决方案,我会很高兴的什么是MyAllocatedData
?C结构?Acdef类
?一种Python对象?一种C类型。具体来说,是一个结构。你想要C和Cython中的确切结构定义吗?我认为这些细节无关紧要。但它如何“不起作用”?你能举个例子吗?@delnan这很公平,对不起。我现在给出了一个完整的例子,问题不在于分配数据的方式,而在于将指针传递给构造函数的方式。传递空指针将导致相同的错误