Cython:将 C 结构转换为 pythons 对象会增加引用计数
Posted
技术标签:
【中文标题】Cython:将 C 结构转换为 pythons 对象会增加引用计数【英文标题】:Cython: casting C struct to pythons object increases refcount 【发布时间】:2019-06-20 11:40:17 【问题描述】:我正在尝试将 C 指针结构转换为对象类型,这样做时,无论该字段是什么类型,该结构的第一个字段都将递增 1。 这种行为是预期的吗?我不应该将 C 指针转换为对象,或者 Cython 有问题?
示例代码:
C 结构:
struct attr
int a;
;
赛通: 像素:
cdef class Attr(object):
cdef attr * t
pyx:
cdef class Attr(object):
__init__(self):
self.t = malloc(sizeof(attr))
self.t.a = 0
attr(self):
return <object>self.t
在创建 Attr 并运行 attr 方法时,t 结构的“a”字段正在递增 (这个例子只是我试图不运行的例子) 感谢您的帮助
【问题讨论】:
【参考方案1】:是的,这是意料之中的。
您的目标可能是 Cython 能够在 C 结构和 Python 字典之间自动转换。无需在您的 Cython 代码中添加 <>
即可发生这种情况。为了让它工作,你需要告诉 Cython 结构成员。不过,您确实需要取消对指针的引用:return self.t[0]
。
对<object>
的强制转换告诉 Cython:“这个指针可以直接解释为 PyObject*
,我们现在负责对它进行引用计数。” C API 的模式是,您有各种不同的结构,都声明为以PyObject_HEAD
开头。然后,您可以将它们转换为PyObject*
,因为结构开头的内存布局是相同的。由于您的结构没有这种模式,您会得到无意义的结果。
(附录) 我认为值得补充的是:这有可能比现在看起来更可怕。如果 Python 认为“引用计数”达到 0,那么 Python 将尝试释放该对象。 PyObject
的第二部分是指向定义类型的PyTypeObject
的指针。一大堆事情(例如,释放、打印对象、几乎任何与 Python 的交互)都可能导致 Python 尝试查找此类型对象,并且由于该结构不包含指向有效 PyTypeObject
的指针,因此这最终会大大失败。
【讨论】:
以上是关于Cython:将 C 结构转换为 pythons 对象会增加引用计数的主要内容,如果未能解决你的问题,请参考以下文章
在 cython 中将 C++ 对象转换为 python 对象?
如何在 Cython 中将 Python 对象转换为 C++ 类型
使用 cx_Freeze 将 Python 转换为 exe 时 Scipy 和 Cython 出现 AttributeError