在python中洗牌ctype数组

在python中洗牌ctype数组,python,arrays,ctypes,Python,Arrays,Ctypes,我想洗牌一个ctype数组。当我尝试使用random.shuffle(myArray)时,我得到一个错误(builtins.ValueError:PyObject为NULL) 我认为您应该使用ctypes.c\u int而不是ctypes.py\u object ctypes定义了许多与C兼容的基本数据类型。 random.shuffle只需交换随机索引值的项即可工作。如果您首先初始化数组,以便不取消对空指针的引用,则没有问题: >>> import ctypes, rando

我想洗牌一个ctype数组。当我尝试使用
random.shuffle(myArray)
时,我得到一个错误(
builtins.ValueError:PyObject为NULL

我认为您应该使用
ctypes.c\u int
而不是
ctypes.py\u object

ctypes定义了许多与C兼容的基本数据类型。

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_对象
而不是常规的C类型。这很不寻常。除非您真的需要将Python对象数组传递给库,否则您应该使用常规C类型,如
C_long
C_double
,等等。这些类型将Python对象的值转换为C数据类型


这里有更多关于py_对象的内容(键入“O”)。它是一种简单的指针类型,如
c\u void\u p
(type'p')。所谓简单类型,我的意思是它是
\ctypes的一个子类。\u SimpleCData
而不是
\ctypes.\u Pointer
,因此它有一个
属性而不是
内容
py_对象
专门指向Python对象,在CPython中,Python对象是对象的
id
。构造函数在
\u 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
(用于获取数组项、结构字段或函数调用结果)返回对Python对象的新引用。但它首先检查
NULL
。这就是您得到的
ValueError
的来源。相反,在这种情况下,
c\u void\u p
的值仅返回
None

>>> arr = (ctypes.c_void_p * 5)()
>>> random.shuffle(arr) # silly this is
>>> arr[:]
[None, None, None, None, None]
>>> 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
>>> arr = (ctypes.c_void_p * 5)()
>>> random.shuffle(arr) # silly this is
>>> arr[:]
[None, None, None, None, None]