【问题标题】:Return malloc'ed array from C to Python using ctypes使用 ctypes 将 malloc 的数组从 C 返回到 Python
【发布时间】:2014-08-20 15:45:13
【问题描述】:

我希望使用一些返回多个未知大小数组的 C 代码。因为有多个数组,我想我需要使用传入的指针,我不知道如何将它与用于设置数组的 malloc 结合起来。

这是一些有代表性的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;
}

我正在尝试通过以下方式将它与 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

这不起作用,我永远无法打印出 20。有什么想法吗?

【问题讨论】:

  • 能否请您发布错误或您得到的任何输出?
  • 你的意思是,作为回报多个数组?你不能直接返回int**吗?
  • 另外,顺便说一句,malloc 返回一个指向数据的指针,你不需要强制转换:(int *)
  • 目前没有错误,只是输出错误(一些随机数)

标签: python c arrays ctypes ctype


【解决方案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]

编辑:您应该考虑提供一个函数来释放 malloc 的数据。所以你可以这样做,例如dll.cleanup(data1, data2)

【讨论】:

  • 在我的情况下,CDLL('test.so') 不工作,但 CDLL('./test.so') 工作。为什么会这样?
  • Python free malloced 有内存吗?
【解决方案2】:

你需要指向指针的指针:

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;
}

我不知道python部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    相关资源
    最近更新 更多