使用ctypes传递数组

我有一个C函数

void read_FIFO_AI0(int16_t** input, size_t size, NiFpga_Session* session, NiFpga_Status* status) { *input = (int16_t*) malloc (size*sizeof(int16_t)); // function that populates the array *input } 

填充数组“* input”。 现在我想将该数组中的数据传递给python进行进一步处理。 我尝试使用ctypes来做到这一点:

 def read_FIFO_AI0(size,session,status): _libfpga.read_FIFO_AI0.argtypes = [POINTER(ARRAY(c_int16, size)), c_int, POINTER(c_uint32), POINTER(c_int32)] _libfpga.read_FIFO_AI0.restype = None values = (c_int16*size)() _libfpga.read_FIFO_AI0(byref(values),size,byref(session),byref(status)) return values 

代码执行但我在数组中得到错误的结果。 当我尝试在CI中使用C函数时获得正确的结果:

 size_t size=20; int16_t* input; read_FIFO_AI0(&input, size, &session, &status); 

填充数组的正确方法是什么,以便我可以在Python中访问数据? 我没有使用指向已填充的数组的指针,我也可以在C函数中创建数组并将其作为返回Python发送,但我也没有开始工作。

第一个参数的类型是POINTER(POINTER(c_int16))而不是POINTER(ARRAY(c_int16,size))

这是一个简短的例子:

xc(用cl /LD xc编译:

 #include  #include  __declspec(dllexport) void read(int16_t** input, size_t size) { int i; int16_t* p = (int16_t*) malloc (size*sizeof(int16_t)); for(i=0;i 

x.py

 from ctypes import * x = CDLL('x') x.read.argtypes = [POINTER(POINTER(c_int16))] x.read.restype = None x.release.argtypes = [POINTER(c_int16)] x.release.restype = None p = POINTER(c_int16)() x.read(p,5) for i in range(5): print(p[i]) x.release(p) 

输出:

 0 1 2 3 4 

请注意,如果您不记得free malloc则会留下潜在的内存泄漏。 更好的方法是在Python中分配缓冲区并告诉C函数大小:

XC

 #include  #include  __declspec(dllexport) void read(int16_t* input, size_t size) { int i; for(i=0;i 

x.py

 from ctypes import * x = CDLL('x') x.read.argtypes = [POINTER(c_int16)] x.read.restype = None p = (c_int16*5)() x.read(p,len(p)) print(list(p)) 

产量

 [0, 1, 2, 3, 4]