如何在Cython 3.0+中获取memoryview底层数据的指针?
在Cython 3.0+中获取ndarray底层数据指针的正确方法(兼容NPY_1_7)
在Cython 3.0+版本中,直接访问ndarray.data已被弃用,以下是两种符合NPY_1_7 C-API和Cython 3.0+规范的获取底层数据指针的方法:
方法一:通过memoryview直接获取指针(推荐)
利用Cython对memoryview的原生支持,直接通过取地址运算符&获取底层数据指针,这是最简洁且符合新API的方式:
import numpy as np def main(): arr = np.zeros((10,), dtype=np.float64) # 将ndarray转为memoryview,再获取指针 cdef double[:] mv = arr cdef double* arr_data = &mv[0] do_something_to_arr_data_in_cythonorcpp(arr_data) print(arr) cdef do_something_to_arr_data_in_cythonorcpp(double* arr_data): for idx in range(10): arr_data[idx] += idx
说明:
- 先将ndarray转换为指定类型的memoryview(
double[:]对应float64类型的一维数组) - 通过
&mv[0]直接获取数组首元素的指针,该指针可直接传递给C/C++风格的函数
方法二:使用Numpy C-API的PyArray_DATA宏(兼容NPY_1_7)
如果需要更贴近Numpy底层C-API的实现,可以使用PyArray_DATA宏来获取指针,这种方式完全符合NPY_1_7规范:
import numpy as np # 导入Numpy的C-API头文件 cimport numpy as np def main(): arr = np.zeros((10,), dtype=np.float64) # 通过PyArray_DATA获取底层数据指针 cdef double* arr_data = <double*>np.PyArray_DATA(arr) do_something_to_arr_data_in_cythonorcpp(arr_data) print(arr) cdef do_something_to_arr_data_in_cythonorcpp(double* arr_data): for idx in range(10): arr_data[idx] += idx
说明:
- 需要通过
cimport numpy导入Numpy的C-API定义 PyArray_DATA宏会直接返回ndarray底层数据的void*指针,需要通过显式类型转换<double*>转为对应的数据类型指针
注意事项
- 确保ndarray的 dtype 与指针类型匹配(比如
float64对应double*,float32对应float*) - 如果处理多维数组,需要自行计算元素的内存偏移(可以结合
PyArray_STRIDES宏获取步长)
内容的提问来源于stack exchange,提问作者ajl123
相关产品推荐
相关产品推荐

