You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cython访问结构体指针报错:Storing unsafe C derivative of temporary Python reference

解决Cython访问C结构体指针成员的编译错误

让我来帮你拆解这个问题的根源,然后一步步修复它:

错误原因

你遇到的两个编译错误,本质都是Cython没把ptr_list当成真正的C结构体来处理:

  • 在你的.pxd文件里,你定义了包含_heap_ptr的_list结构体,但又单独声明了一个空的ptr_list结构体(ctypedef struct ptr_list: pass)。Cython完全不知道这两个结构体之间有什么关系,所以当你访问basic_list._heap_ptr时,它会误以为basic_list是个Python对象,而非C结构体实例——这就解释了为什么会报错"Cannot convert Python object to 'int *'"。
  • 另外,_heap_ptr是void*类型,Cython不会自动帮你把void*转换成int*,必须显式做类型转换,这也是错误的诱因之一。

修复方案

第一步:修正.pxd的结构体声明

首先要让Cython知道ptr_list和_heap_ptr的关联,这取决于你的C头文件里ptr_list的实际定义,分两种情况:

情况1:ptr_list是_list的直接别名

如果你的C代码里是这么定义的:

typedef struct _list {
    void* _heap_ptr;
    // 其他成员
} ptr_list;

那直接把.pxd里的结构体声明合并,明确定义ptr_list的内部成员:

cdef extern from "src/list.h":
    ctypedef struct ptr_list:
        void* _heap_ptr  # 直接在这里声明结构体成员

    ptr_list create_list_size(size_t size, int length)
    list_destroy(ptr_list this_list)
    void* list_at_ptr(ptr_list this_list, int index)
    list_add_ptr(ptr_list this_list, void* value)

情况2:ptr_list是指向_list的指针

如果你的C代码里ptr_list是指针类型(比如typedef struct _list* ptr_list;),那要在.pxd里把它声明为指针:

cdef extern from "src/list.h":
    ctypedef struct _list:
        void* _heap_ptr

    ctypedef _list* ptr_list  # 明确ptr_list是_list的指针类型

    ptr_list create_list_size(size_t size, int length)
    list_destroy(ptr_list this_list)
    void* list_at_ptr(ptr_list this_list, int index)
    list_add_ptr(ptr_list this_list, void* value)

这种情况下,访问成员要改用->,比如basic_list->_heap_ptr。

第二步:给指针做显式类型转换

因为_heap_ptr是void*,必须显式转换成int*才能赋值给arr,修改你的.pyx代码:

# 对应情况1(ptr_list是结构体)
arr = <int*>basic_list._heap_ptr

# 对应情况2(ptr_list是指针)
arr = <int*>basic_list->_heap_ptr

修正后的完整.pyx示例(情况1)

cimport src.clist as l

def main():
    cdef l.ptr_list basic_list
    cdef int i = 42
    basic_list = l.create_list_size(sizeof(i), 100)
    l.list_add_ptr(basic_list, &i)
    
    cdef int* arr
    arr = <int*>basic_list._heap_ptr  # 显式转换void*到int*
    
    for i in range(1):
        print(arr[i])

这样修改后,Cython就能正确识别ptr_list是C结构体,顺利访问_heap_ptr成员,编译错误也就解决了。

内容的提问来源于stack exchange,提问作者The Unfun Cat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:57:23