[英]ctypes segmentation fault 11 on OSX 10.10 when passing large arrays
[英]passing arrays with 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))
。
這是一個簡短的例子:
cl /LD xc
編譯: #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);
}
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)
0
1
2
3
4
請注意,如果您不記得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;
}
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))
[0, 1, 2, 3, 4]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.