如何通过ctypes将Python列表转换为C数组?

64 投票
4 回答
76948 浏览
提问于 2025-04-16 06:51

如果我有以下两段代码,我该如何把它们连接在一起呢?

void
c_function(void *ptr) {
    int i;

    for (i = 0; i < 10; i++) {
        printf("%p", ptr[i]);
    }

    return;
}


def python_routine(y):
    x = []
    for e in y:
        x.append(e)

我该如何用一个连续的元素列表来调用 c_function 呢?我试着把 x 转换成 c_void_p,但没有成功。

我还尝试使用类似的东西:

x = c_void_p * 10 
for e in y:
    x[i] = e

但是这出现了语法错误。

这段 C 代码显然需要一个数组的地址。我该如何做到这一点呢?

4 个回答

13

来自ctypes教程

>>> IntArray5 = c_int * 5
>>> ia = IntArray5(5, 1, 7, 33, 99)
24

这是对被接受答案的解释。

ctypes.c_int * len(pyarr) 创建了一个长度为4的 c_int 类型数组(序列),这个长度是根据 pyarr 的长度来决定的(python3, python 2)。因为 c_int 是一个对象,它的构造函数需要一个参数,所以 (ctypes.c_int * len(pyarr)(*pyarr) 这段代码会一次性初始化每个来自 pyarrc_int 实例。更容易理解的写法是:

pyarr = [1, 2, 3, 4]
seq = ctypes.c_int * len(pyarr)
arr = seq(*pyarr)

使用 type 函数来查看 seqarr 之间的区别。

117

下面的代码可以在任意列表上运行:

import ctypes
py_values = [1, 2, 3, 4]
arr = (ctypes.c_int * len(py_values))(*py_values)

撰写回答