python - ctypes.cast works in python2 and throws ArgumentError in python3 -
i'm having issue ctypes code works in python2 fails in python3.
the function i'm failing in arrptr_to_np, trying take array created in external c library , load numpy array.
the function looks this
def arrptr_to_np(c_arrptr, shape, arr_t, dtype): """ casts array pointer c numpy args: c_arrpt (uint64): pointer array returned c shape (tuple): shape of underlying array being pointed arr_t (pycsimpletype): ctypes datatype of c_arrptr dtype (dtype): numpy datatype array cast """ 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 ctypes np_arr = np.ctypeslib.as_array(c_arr, shape) np_arr.dtype = dtype return np_arr these values of variables in example i'm working
varname - value - type(var)
c_arrptr - 20622304 - numpy.uint64
shape - (506, 6) - tuple
arr_t - numpy.ctypeslib.ndpointer_< f4_2d_aligned_c_contiguous_writeable - _ctypes.pycsimpletype
dtype - np.float32 - np.float32
these same between python2 , python3 versions (except value of pointer of course, still uint64)
when execute function works expected in python2. however, in python3 error on line
c_arr = c.cast(typed_c_arrptr, dtype_ptr_t) # cast ctypes the error argumenterror
/usr/lib/python3.4/ctypes/__init__.py in cast(obj, typ) 487 def cast(obj, typ): --> 488 return _cast(obj, obj, typ) 489 argumenterror: argument 1: <class 'typeerror'>: wrong type during handling of above exception, exception occurred: argumenterror traceback (most recent call last) in <module>() ----> 1 c_arr = c.cast(typed_c_arrptr, dtype_ptr_t) # cast ctypes /usr/lib/python3.4/ctypes/__init__.py in cast(obj, typ) 486 _cast = pyfunctype(py_object, c_void_p, py_object, py_object)(_cast_addr) 487 def cast(obj, typ): --> 488 return _cast(obj, obj, typ) 489 490 _string_at = pyfunctype(py_object, c_void_p, c_int)(_string_at_addr) argumenterror: argument 1: <class 'typeerror'>: wrong type at point in code execution typed_c_arrptr dtype('int64') in both versions of program. dtype_ptr_t lp_c_char_array_4 in both versions.
i've tried many variations on typed_c_arrptr = c_arrptr.astype(int) replacing int ctypes.c_int, ctypes.c_long, ctypes.c_size_t. @ point i'm guessing , going wrong. on appreciated.
the error tell you, first argument couldn't converted ctypes.c_void_p. typed_c_arrptr couldn't converted.
this happens, because astype() works differently int both versions of python. python 3 have
>>> isinstance(np.uint64(12345).astype(int), int) false and therefore ctypes doesn't know how convert np.uint64. whereas python 2 have
>>> isinstance(np.uint64(12345).astype(int), int) true so ctypes treats if int.
further the documentation of generic.astype() reads
not implemented (virtual attribute)
class generic exists solely derive numpy scalars from, , possesses, albeit unimplemented, attributes of ndarray class provide uniform api.
and have no idea, why works python 2.
instead use int() convert np.uint64 cast ctypes.c_void_p. worked me both versions.
c_arr = c.cast(int(c_arrptr), dtype_ptr_t)
Comments
Post a Comment