【问题标题】:What does (ctypes.c_int * len(x))(*x) do?(ctypes.c_int * len(x))(*x) 做什么?
【发布时间】:2016-05-16 06:56:28
【问题描述】:

我正在使用 pyOpenGL,而 OpenGL 要求我通过传递指针和要传输的字节数来传输数据。

我知道 python 不会像 c 那样将变量存储在内存中。我发现以下代码可以使我的程序正常工作:

x = [1, 2, ... ]              # some list
(ctypes.c_int * len(x))(*x)

但是我不知道它为什么会起作用(而且我不只是想相信我还没有幸运地看到一切都进入了记忆)。这段代码实际上在做什么?

【问题讨论】:

  • 你没有提到你正在使用什么,但你可以使用 sizeof 来获取要传输的字节数。例如:cx = (ctypes.c_int * len(x))(*x);num_bytes = ctypes.sizeof(cx)
  • 我假设您将数组作为 C 函数参数传递。这是因为 ctypes 数组,就像 C 数组一样,作为指向第一个元素的指针传递。
  • 是的,它作为 C 函数参数传递。

标签: python ctypes


【解决方案1】:

根据Python documentation

推荐的创建具体数组类型的方法是乘以 任何具有正整数的 ctypes 数据类型。 或者,您可以 子类这个类型并定义 lengthtype 类变量。 数组元素可以使用标准下标读写 切片访问;对于切片读取,结果对象本身不是 数组。

例子:

>>> from ctypes import *
>>> TenIntegers = c_int * 10
>>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>>> print ii
<c_long_Array_10 object at 0x...>
>>> for i in ii: print i,
...
1 2 3 4 5 6 7 8 9 10
>>>

所以,第一部分 ctypes.c_int * len(x) 创建了一个带有 len(x) 元素的数组类型:

In [17]: ctypes.c_int * 10
Out[17]: __main__.c_int_Array_10

In [18]: ctypes.c_int * 100
Out[18]: __main__.c_int_Array_100

类型创建后,你应该调用它并传递数组元素:

(ctypes.c_int * len(x))(*x)
#                      ^^^^

创建的数组类型接受可变数量的元素,所以,你应该expand list x using the *x form:

In [24]: x = [1, 2, 3]

In [25]: (ctypes.c_int * len(x))(*x)
Out[25]: <__main__.c_int_Array_3 at 0x7f0b34171ae8>

In [26]: list((ctypes.c_int * len(x))(*x))
Out[26]: [1, 2, 3]

In [27]: (ctypes.c_int * len(x))(*x)[1]
Out[27]: 2

您不能传递x,因为__init__ 需要整数:

In [28]: (ctypes.c_int * len(x))(x)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-ff45cb7481e4> in <module>()
----> 1 (ctypes.c_int * len(x))(x)

TypeError: an integer is required (got type list)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-10
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 2020-12-15
    • 2013-01-30
    相关资源
    最近更新 更多