如何使用 ctypes 将 Python 列表转换为 C 数组?

Posted

技术标签:

【中文标题】如何使用 ctypes 将 Python 列表转换为 C 数组?【英文标题】:How do I convert a Python list into a C array by using ctypes? 【发布时间】:2011-05-07 22:37:40 【问题描述】:

如果我有以下 2 组代码,如何将它们粘合在一起?

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)

如何使用 x 中的连续元素列表调用 c_function?我试图将 x 转换为 c_void_p,但这没有用。

我也尝试使用类似的东西

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

但这会出现语法错误。

C 代码显然需要数组的地址。我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

以下代码适用于任意列表:

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

【讨论】:

"*pyarr" in python...是什么意思? @AaronYC 很抱歉造成混乱; pyarr 是一个普通的python 列表,如pyar = [1,2,3,4]。如果您想知道名称前的星号,请查看:***.com/questions/400739/what-does-mean-in-python 不错的答案,但对我们未洗过的人来说有点油嘴滑舌。 @Jiminion 请参阅下面的答案以了解语法说明。 很好,现在如何释放arr 变量?当然,我们不必在这里使用 C 中的free() 吗?【参考方案2】:

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

ctypes.c_int * len(pyarr) 创建一个长度为 4 的 c_int 类型的数组(序列)(python3,python 2)。由于c_int 是一个其构造函数采用一个参数的对象,(ctypes.c_int * len(pyarr)(*pyarr) 对来自pyarr 的每个c_int 实例进行一次初始化。 easier to read 表单是:

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

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

【讨论】:

【参考方案3】:

来自the ctypes tutorial:

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

【讨论】:

尝试创建超过 255 个项目的数组。 适用于超过 255 个项目:IntArray300 = c_int * 300; arrayWith300Elements=IntArray300(*list([i for i in range(300)]))【参考方案4】:
import ctypes
import typing

def foo(aqs : typing.List[int]) -> ctypes.Array:
    array_type = ctypes.c_int64 * len(aqs)
    ans = array_type(*aqs)
    return ans

for el in foo([1,2,3]):
    print(el)

这将给出:

1
2
3

【讨论】:

以上是关于如何使用 ctypes 将 Python 列表转换为 C 数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 ctypes 的 c_long 转换为 Python 的 int?

将 ctypes int** 转换为 numpy 二维数组

使用 ctypes 将 python dict 转换为结构

使用 ctypes 将 python 字符串对象转换为 c char*

如何使用 ctypes 将此 Python 对象移动到 C++ 中?

Python - 将字符串对象转换为 ctypes (unsigned char *)