问题
I am looking to use some C code that returns multiple arrays of unknown size. Because there are multiple arrays, I think I need to use passed in pointers, and I'm not sure how to combine that with malloc, which is used to setup the arrays.
This is some representative C code:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
//gcc -fPIC -shared -o array_test_c.so array_test_c.c
void return_array(int * outdata1v, int * outdata2v) {
int i;
int N = 10;
int * mydatav2, * mydatav3;
mydatav2 = (int *) malloc(sizeof(int) * N);
mydatav3 = (int *) malloc(sizeof(int) * N);
for (i = 0; i<N; i++){
mydatav2[i] = i;
mydatav3[i] = i*2;
}
//this doesn't work which makes sense
outdata1v = mydatav2;
outdata2v = mydatav3;
}
And I'm trying to hook it to Python with something along these lines (this does not work):
import os
import ctypes
#for c interface
test_module = ctypes.cdll.LoadLibrary(
os.path.join(os.path.dirname(__file__), './array_test_c.so'))
outdata1 = (ctypes.c_int * 0)()
outdata2 = (ctypes.c_int * 0)()
test_module.return_array(outdata1, outdata2)
outdata1 = (ctypes.c_int*10).from_address(ctypes.addressof(outdata1))
print "out", outdata1[-1], outdata1, outdata2
This does not work, and I can never get 20 to print out. Any ideas?
回答1:
test.c
#include <stdlib.h>
#define N 10
void test(int *size, int **out1, int **out2) {
int i;
int *data1, *data2;
data1 = (int *)malloc(sizeof(int) * N);
data2 = (int *)malloc(sizeof(int) * N);
for (i = 0; i < N; i++){
data1[i] = i;
data2[i] = i * 2;
}
*size = N;
*out1 = data1;
*out2 = data2;
}
test.py
from ctypes import CDLL, POINTER, c_int, byref
dll = CDLL('test.so')
data1 = POINTER(c_int)()
data2 = POINTER(c_int)()
size = c_int()
dll.test(byref(size), byref(data1), byref(data2))
for i in range(size.value):
print i, data1[i], data2[i]
Edit: You should consider providing a function to free the malloc'd data. So you can then do, e.g. dll.cleanup(data1, data2)
回答2:
You need pointers to pointers:
void return_array(int **outdata1v, int **outdata2v) {
int i;
int N = 10;
int * mydatav2, * mydatav3;
mydatav2 = (int *) malloc(sizeof(int) * N);
mydatav3 = (int *) malloc(sizeof(int) * N);
for (i = 0; i<N; i++){
mydatav2[i] = i;
mydatav3[i] = i*2;
}
*outdata1v = mydatav2;
*outdata2v = mydatav3;
}
I don't know about the python part.
来源:https://stackoverflow.com/questions/25409073/return-malloced-array-from-c-to-python-using-ctypes