如何通过Python ctypes将NumPy数组传入C++ DLL的unsigned short**指针?
解决Python ctypes传递NumPy数组给C++ DLL的unsigned short**参数问题
问题根源
你的C函数do_calc接收的是二级指针(unsigned short**),但你之前的两种调用方式都只传递了NumPy数组的一级指针(unsigned short*)。C函数会把传入的一级指针当作二级指针去解引用,相当于把数组第一个元素的数值当成内存地址访问,这必然导致内存访问违规。
正确实现步骤
1. 确保NumPy数组类型匹配
首先要保证你的NumPy数组是uint16类型(对应C++的unsigned short),并且是连续内存布局(避免非连续数组导致的问题):
import numpy as np import ctypes # 构造符合要求的NumPy数组 np_array = np.array([1,2,3,4], dtype=np.uint16) # 确保数组是C连续的(可选,但推荐) np_array = np.ascontiguousarray(np_array)
2. 构造二级指针传入C++函数
有两种可靠的方式构造二级指针:
方式一:显式创建二级指针类型
libhandle = ctypes.CDLL(library_path) libhandle.do_calc.argtypes = [ctypes.POINTER(ctypes.POINTER(ctypes.c_ushort))] libhandle.do_calc.restype = ctypes.c_int # 获取数组的一级指针 array_ptr = np_array.ctypes.data_as(ctypes.POINTER(ctypes.c_ushort)) # 构造二级指针:传递一级指针的地址 error_code = libhandle.do_calc(ctypes.byref(array_ptr))
方式二:用c_void_p包装二级指针
如果你不想显式声明二级指针类型,也可以用c_void_p传递一级指针的地址:
libhandle = ctypes.CDLL(library_path) libhandle.do_calc.argtypes = [ctypes.c_void_p] libhandle.do_calc.restype = ctypes.c_int array_ptr = np_array.ctypes.data_as(ctypes.POINTER(ctypes.c_ushort)) # 把一级指针的地址转成void*传入 error_code = libhandle.do_calc(ctypes.cast(ctypes.byref(array_ptr), ctypes.c_void_p))
3. C++函数的注意事项
如果你的C++函数需要知道数组长度,建议修改函数签名增加长度参数,避免越界访问:
int do_calc(unsigned short** input_array, int array_length) { // 使用array_length控制访问范围 for(int i=0; i<array_length; i++){ unsigned short val = (*input_array)[i]; // 处理逻辑 } return 0; }
对应的Python调用也要补充长度参数:
libhandle.do_calc.argtypes = [ctypes.POINTER(ctypes.POINTER(ctypes.c_ushort)), ctypes.c_int] error_code = libhandle.do_calc(ctypes.byref(array_ptr), ctypes.c_int(np_array.size))
内容的提问来源于stack exchange,提问作者user219249
相关产品推荐
相关产品推荐

