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

Popular posts from this blog

android - Pass an Serializable object in AIDL -

How to provide Authorization & Authentication using Asp.net, C#? -

How to use Authorization & Authentication in Asp.net, C#? -