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 代码中添加 &lt;&gt; 即可发生这种情况。为了让它工作,你需要告诉 Cython 结构成员。不过,您确实需要取消对指针的引用:return self.t[0]

&lt;object&gt; 的强制转换告诉 Cython:“这个指针可以直接解释为 PyObject*,我们现在负责对它进行引用计数。” C API 的模式是,您有各种不同的结构,都声明为以PyObject_HEAD 开头。然后,您可以将它们转换为PyObject*,因为结构开头的内存布局是相同的。由于您的结构没有这种模式,您会得到无意义的结果。


(附录) 我认为值得补充的是:这有可能比现在看起来更可怕。如果 Python 认为“引用计数”达到 0,那么 Python 将尝试释放该对象。 PyObject 的第二部分是指向定义类型的PyTypeObject 的指针。一大堆事情(例如,释放、打印对象、几乎任何与 Python 的交互)都可能导致 Python 尝试查找此类型对象,并且由于该结构不包含指向有效 PyTypeObject 的指针,因此这最终会大大失败。

【讨论】:

以上是关于Cython:将 C 结构转换为 pythons 对象会增加引用计数的主要内容,如果未能解决你的问题,请参考以下文章

使用Cython将结构从C返回到Python

在 cython 中将 C++ 对象转换为 python 对象?

如何在 Cython 中将 Python 对象转换为 C++ 类型

使用 cx_Freeze 将 Python 转换为 exe 时 Scipy 和 Cython 出现 AttributeError

将 C 代码转换为 Web 程序集时出错

Cython 和 SIMD 内在函数:防止 SIMD 内在函数的参数转换为 python 对象