在python中随机播放一个ctype数组

时间:2013-11-22 01:49:24

标签: python arrays ctypes

我想要改组ctype数组。当我尝试random.shuffle(myArray)时出现错误(builtins.ValueError: PyObject is NULL

    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 个答案:

答案 0 :(得分: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属性而不是contentspy_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_p的{​​{3}}只返回None

>>> arr = (ctypes.c_void_p * 5)()
>>> random.shuffle(arr) # silly this is
>>> arr[:]
[None, None, None, None, None]

答案 1 :(得分: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