2013-11-22 59 views
0

我想隨機播放一個ctype數組。當我嘗試了random.shuffle(myArray)我得到一個錯誤(builtins.ValueError: PyObject is NULL在python中隨機播放ctype數組

import ctypes 
    import random 

    def shuffleArray(): 
     size = 10 
     myArray = (size*ctypes.py_object)() 
     random.shuffle(myArray) 
     for i in range(0,size): 
     myArray[i] = i 
     print(myArray[i]) 

回答

2

random.shuffle通過簡單地交換隨機索引值的項來工作。有沒有問題,如果你第一次初始化數組,以便不提領一空指針:

>>> import ctypes, random 
>>> my_array = (10 * ctypes.py_object)(*range(10)) 
>>> random.shuffle(my_array) 
>>> my_array[:] 
[5, 0, 4, 8, 6, 3, 7, 1, 2, 9] 

我不知道爲什麼你需要py_object,而不是一個常規的C型。這很不尋常。除非你真的需要將一個Python對象數組傳遞給一個庫,否則你應該使用常規的C類型,例如c_longc_double等。這些類型將Python對象的值轉換爲C數據類型。


下面是關於py_object(類型'O')的更多信息。這是一個簡單的指針類型,如c_void_p(鍵入'P')。通過簡單類型,我的意思是它是_ctypes._SimpleCData的子類而不是_ctypes._Pointer,因此它具有value屬性而不是contents。 A py_object特別指向一個Python對象,該對象在CPython中是該對象的id。構造函數保留對_objects屬性中對象的引用。這可以防止垃圾收集引用的對象。

>>> obj = 'abc' 
>>> pyobj = ctypes.py_object(obj) 

>>> pyobj._objects is obj 
True 
>>> addr = ctypes.c_size_t.from_buffer(pyobj).value 
>>> addr == id(obj) 
True 

type 'O' GETFUNC(用於獲取一個數組項,結構字段中,或函數調用結果)返回一個新的參考Python對象。但它首先檢查NULL。這就是你所得到的ValueError的來源。相反,在這種情況下,c_void_ptype 'P' GETFUNC僅僅返回None

>>> arr = (ctypes.c_void_p * 5)() 
>>> random.shuffle(arr) # silly this is 
>>> arr[:] 
[None, None, None, None, None] 
0
import ctypes 
import random 
def shuffleArray(): 
    size = 10 
    myArray = (size * ctypes.c_int)() 
    random.shuffle(myArray) 
    for i in range(0, size): 
     myArray[i] = i 
     print(myArray[i]) 
shuffleArray() 

我認爲你應該使用ctypes.c_int而不是ctypes.py_object

ctypes定義了許多基本的C兼容數據類型。 http://docs.python.org/2/library/ctypes.html