关于python:(ctypes.c_int * len(x))(* x)做什么?

What does (ctypes.c_int * len(x))(*x) do?

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

我理解python并不像c那样在内存中存储变量。我找到了使我的程序工作的以下代码:

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

然而,我不知道它为什么会起作用(我不只是想相信,我并没有因为所有的事情都进入记忆而幸运)。这段代码实际上在做什么?


根据《Python文档:

The recommended way to create concrete array types is by multiplying
any ctypes data type with a positive integer. Alternatively, you can
subclass this type and define length and type class variables.
Array elements can be read and written using standard subscript and
slice accesses; for slice reads, the resulting object is not itself an
Array.

Example:

1
2
3
4
5
6
7
8
9
>>> 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)

1
2
3
4
5
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

你应该创建后,呼叫类型,数组元素:IT和通

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

创建数组的元素类型variadic接受数,因此,你应该使用*x形式x扩展列表:

1
2
3
4
5
6
7
8
9
10
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__expects整数:

1
2
3
4
5
6
7
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)