简体   繁体   English

使用ctypes将malloc的数组从C返回到Python

[英]Return malloc'ed array from C to Python using ctypes

I am looking to use some C code that returns multiple arrays of unknown size. 我正在寻找使用一些C代码来返回未知大小的多个数组。 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. 因为有多个数组,所以我认为我需要使用传入的指针,而且我不确定如何将其与用于设置数组的malloc结合使用。

This is some representative C code: 这是一些代表性的C代码:

#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): 而且我正在尝试通过以下方式将其连接到Python(这不起作用):

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. 这是行不通的,我永远也无法打印20张。 Any ideas? 有任何想法吗?

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 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. 编辑:您应该考虑提供释放malloc数据的功能。 So you can then do, eg dll.cleanup(data1, data2) 这样就可以进行操作,例如dll.cleanup(data1, data2)

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. 我不了解python部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM