Cython中Py_INCREF仅接受Python对象而非指针的问题排查
问题解决:Cython中Py_INCREF操作PyObject*指针报错
问题根源
Cython默认提供的Py_INCREF是针对Python层级object类型的包装,并非直接对应C API中接受PyObject*的原始版本。这就是你传入PyObject*时触发类型转换错误,而传入原始object参数能正常工作的核心原因。
解决方案
要直接操作PyObject*指针并调用C API版本的Py_INCREF,需要显式导入Cython对CPython对象API的封装:
- 在代码顶部添加
cimport cpython.object,引入CPython对象API的Cython绑定 - 使用
cpython.object.Py_INCREF替代默认的Py_INCREF,即可直接传入PyObject*指针
修改后的示例代码:
cimport cpython.object # 导入CPython对象API的Cython封装 ctypedef struct Node: PyObject* group PyObject* value # (group, value) Node* next cdef bint _put(object group, object value) except 1: cdef: Node* node = <Node*>PyMem_Malloc(sizeof(Node)) PyObject* _group = <PyObject*> group PyObject* _value = <PyObject*> value if not node: raise MemoryError("Failed to allocate memory for new node") node.group = _group cpython.object.Py_INCREF(node.group) # 可正常操作PyObject*指针 cpython.object.Py_INCREF(_value) # 同样支持PyObject*类型参数 node.value = _value node.next = NULL # 初始化链表节点的next指针 # 此处添加链表插入逻辑... return 0
额外注意事项
- 释放
Node结构体时,必须对应调用cpython.object.Py_DECREF(node.group)和cpython.object.Py_DECREF(node.value),否则会造成Python对象的内存泄漏。 - 若需要处理可能为NULL的指针,可使用
cpython.object.Py_XINCREF(会自动跳过NULL指针,避免崩溃)。
内容的提问来源于stack exchange,提问作者Bharel
相关产品推荐
相关产品推荐

