我遇到了一个问题,我的ctypes代码在python2中工作,但在python3中失败。
我失败的函数是arrptr_to_np,它试图在外部c库中创建一个数组并将其加载到numpy数组中。
函数看起来像这样
def arrptr_to_np(c_arrptr, shape, arr_t, dtype):
"""
Casts an array pointer from C to numpy
Args:
c_arrpt (uint64): a pointer to an array returned from C
shape (tuple): shape of the underlying array being pointed to
arr_t (PyCSimpleType): the ctypes datatype of c_arrptr
dtype (dtype): numpy datatype the array will be to cast into
"""
byte_t = ctypes.c_char
itemsize_ = dtype().itemsize
dtype_t = byte_t * itemsize_
dtype_ptr_t = C.POINTER(dtype_t) # size of each item
typed_c_arrptr = c_arrptr.astype(int)
c_arr = C.cast(typed_c_arrptr, dtype_ptr_t) # cast to ctypes
np_arr = np.ctypeslib.as_array(c_arr, shape)
np_arr.dtype = dtype
return np_arr
这些是我正在使用的示例中变量的值
varname - value - type(var)
c_arrptr - 20622304 - numpy.uint64
shape - (506,6) - tuple
arr_t - numpy. ctypelib .ndpointer_ 错误告诉您,第一个参数无法转换为 这是因为 ,因此ctypes不知道如何转换 所以ctypes只是把它当作一个 进一步 未实现(虚拟属性) 类generic的存在仅仅是为了从narray类派生numpy标量,并且拥有(尽管未实现)narray类的所有属性,从而提供统一的API。 和我不知道,为什么它在Python 2中工作。 相反,您可以使用ctypes.c_void_p
。即typed_c_arrptr
不能被转换。astype()
在两个版本的Python中工作方式不同。在Python 3中,有>>> isinstance(np.uint64(12345).astype(int), int)
False
np.uint64
。而在Python 2中,你有>>> isinstance(np.uint64(12345).astype(int), int)
True
int
。generic.astype()
的文档读int()
将np.uint64
转换为可以强制转换为ctypes.c_void_p
的内容。这在我的两个版本中都有效。c_arr = C.cast(int(c_arrptr), dtype_ptr_t)