eri*_*rik 6 c python arrays 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
}
Run Code Online (Sandbox Code Playgroud)
填充数组"*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
Run Code Online (Sandbox Code Playgroud)
代码执行但我在数组中得到错误的结果.当我尝试在CI中使用C函数时获得正确的结果:
size_t size=20;
int16_t* input;
read_FIFO_AI0(&input, size, &session, &status);
Run Code Online (Sandbox Code Playgroud)
填充数组的正确方法是什么,以便我可以在Python中访问数据?我没有依赖于使用指向已填充的数组的指针,我也可以在C函数中创建数组并将其作为返回Python发送,但我也没有开始工作.
第一个参数的类型POINTER(POINTER(c_int16))不是POINTER(ARRAY(c_int16,size)).
这是一个简短的例子:
cl /LD x.c:#include <stdlib.h>
#include <stdint.h>
__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<size;i++)
p[i] = i;
*input = p;
}
__declspec(dllexport) void release(int16_t* input)
{
free(input);
}
Run Code Online (Sandbox Code Playgroud)
from ctypes import *
x = CDLL('x')
x.read.argtypes = POINTER(POINTER(c_int16)),c_size_t
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)
Run Code Online (Sandbox Code Playgroud)
0
1
2
3
4
Run Code Online (Sandbox Code Playgroud)
注意,这让你有潜在的内存泄漏,如果你不记得free了malloc.更好的方法是在Python中分配缓冲区并告诉C函数大小:
#include <stdlib.h>
#include <stdint.h>
__declspec(dllexport) void read(int16_t* input, size_t size)
{
int i;
for(i=0;i<size;i++)
input[i] = i;
}
Run Code Online (Sandbox Code Playgroud)
from ctypes import *
x = CDLL('x')
x.read.argtypes = POINTER(c_int16),c_size_t
x.read.restype = None
p = (c_int16*5)()
x.read(p,len(p))
print(list(p))
Run Code Online (Sandbox Code Playgroud)
[0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)