2016-02-06 63 views
1

我正在使用pyOpenGL,並且OpenGL要求我通過傳遞一個指針和要傳輸的字節數來傳輸數據。(ctypes.c_int * len(x))(* x)是做什麼的?

我知道python不會像c那樣在內存中存儲變量。我發現下面的代碼,使我的工作方案:

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

但是我不知道爲什麼它的工作原理(我不只是要相信我沒有剛剛得到幸運的一切是如何掉到記憶)。這段代碼實際上在做什麼?

+0

你沒有提到你使用的是什麼這是有效的,但是你可以使用'sizeof'來獲得要傳輸的字節數。例如:'cx =(ctypes.c_int * len(x))(* x);''num_bytes = ctypes.sizeof(cx)'。 – eryksun

+0

我假設你將數組作爲C函數參數傳遞。這是可行的,因爲ctypes數組就像C數組一樣,作爲指向第一個元素的指針傳遞。 – eryksun

+0

是的,它被作爲C函數參數傳遞。 – Francis

回答

4

按照Python documentation

的推薦方法來創建具體數組類型是乘以 具有正整數的任何ctypes的數據類型。或者,您可以 這個類型的子類和定義長度類型類變量。 可以使用標準下標和 切片存取讀取和寫入數組元素;對於片段讀取而言,結果對象本身不是 陣列。

實施例:

>>> 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)