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

如何在Cython的def与cdef函数中使用Python ctypes数组并获取指针?

在Cython中处理ctypes数组的解决方案

首先,你需要在Cython里定义一个和ctypes中Test_Node完全匹配的C结构体类型,保证内存布局一致,这样Cython才能正确解析数组数据。接下来分步骤处理def/cdef函数的调用逻辑,以及获取底层C++指针的方法:

第一步:在Cython中定义匹配的结构体

在你的Cython扩展文件(比如my_cython_extention.pyx)里,先定义和ctypes结构体字段、类型、顺序完全一致的C结构体:

cdef struct Test_Node:
    int i
    float f

这一步是核心,字段的任何不匹配都会导致内存访问错误。

第二步:在Python可见的def函数中接收ctypes数组

def函数是对外暴露的Python接口,可以直接接收ctypes数组对象,通过ctypes.addressof获取底层指针后转换为Cython可操作的类型:

def my_cython_function(ctypes_array):
    # 获取数组第一个元素的内存地址,转换为Cython的Test_Node指针
    cdef Test_Node* arr_ptr = <Test_Node*>ctypes.addressof(ctypes_array[0])
    # 从ctypes数组对象中获取长度
    cdef int length = len(ctypes_array)
    
    # 示例:遍历数组读取/修改数据
    cdef int idx
    for idx in range(length):
        print(f"元素{idx}: i={arr_ptr[idx].i}, f={arr_ptr[idx].f}")
        # 修改数据会同步回原ctypes数组
        arr_ptr[idx].i += 10

第三步:在内部cdef函数中高效操作

如果是Cython内部使用的高性能函数,直接接收指针和长度会更高效,通过def函数做一层转换即可:

# 内部cdef函数,直接操作C指针,性能更高
cdef void _process_array(Test_Node* arr_ptr, int length):
    cdef int idx
    for idx in range(length):
        arr_ptr[idx].f *= 1.5

# 对外的def入口函数
def my_cython_function(ctypes_array):
    cdef Test_Node* arr_ptr = <Test_Node*>ctypes.addressof(ctypes_array[0])
    cdef int length = len(ctypes_array)
    _process_array(arr_ptr, length)

获取C++数据指针

上面代码中的arr_ptr就是底层的C(兼容C++)指针,直接可以传递给C函数使用。如果需要调用外部C代码,只需在Cython中声明C++函数接口即可:

# 声明外部C++函数接口
cdef extern from "your_cpp_header.h":
    void cpp_handle_array(Test_Node* arr, int arr_len)

def my_cython_function(ctypes_array):
    cdef Test_Node* arr_ptr = <Test_Node*>ctypes.addressof(ctypes_array[0])
    cdef int length = len(ctypes_array)
    # 直接将指针传给C++函数
    cpp_handle_array(arr_ptr, length)

注意:编译Cython扩展时需要启用C++支持,比如在setup.py中设置language="c++"。

关键注意事项

  • 务必保证ctypes和Cython的结构体字段类型、顺序、名称完全一致,否则会出现内存越界或数据错乱。
  • 不要手动释放arr_ptr指向的内存,因为内存由Python的ctypes数组对象管理,Python会自动回收。
  • 如果是动态分配的ctypes内存(比如用ctypes.malloc),则需要手动管理内存生命周期,但你的示例中是ctypes数组对象,无需额外处理。

内容的提问来源于stack exchange,提问作者Stepochkin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:52:00