使用ctypes向C DLL传递二维数组遇访问违规问题求助
使用ctypes向C DLL传递二维数组指针遇到访问违规问题
我是ctypes新手,当前项目需通过ctypes向C DLL传递二维数组指针。但DLL已锁定,无法查看修改源码,仅能猜测需传递指向c_ubyte指针的指针。尝试多种方法后,持续出现OSError: exception: access violation reading 0x...错误。
原始代码
加载DLL及调用函数的代码:
# includes the dll file path=os.path.abspath(os.path.dirname(__file__)) winDLL = ct.CDLL(path+'/dlls/slm_win_ctrl.dll') ... # function is called here def update(array): Arr = ndarray2carray(array,"b") winDLL.window_show(pArr) #<---- return
用于将numpy数组转换为ctypes数组的ndarray2carray函数:
def ndarray2carray(ndarr,type): arr_flat = list(ndarr.reshape(-1)) if type == 'd': arr_c = (ct.c_double*len(arr_flat))(*arr_flat) elif type == 'b': arr_c = (ct.c_ubyte*len(arr_flat))(*arr_flat) elif type == 'i': arr_c = (ct.c_int*len(arr_flat))(*arr_flat) elif type == 'f': arr_c = (ct.c_float*len(arr_flat))(*arr_flat) else: print("type_undefine!") print("enter 'b' for byte,'d' for double,'i' for int.") return return arr_c
终端报错:OSError: exception: access violation reading 0x00000267045A72B0
我尝试打印Arr对象和ct.pointer(array),发现地址不同。
第一次修改:添加函数argtypes声明
添加argtypes声明后仍出现访问违规错误:
def update(array): Arr = ndarray2carray(array,"b") pArr = ct.pointer(Arr) winDLL.window_show.argtypes = [type(pArr)] winDLL.window_show.restype = None winDLL.window_show(pArr) return
第二次修改:指定指向指针的指针作为argtype
尝试直接设置argtype为指向指针的指针,出现参数类型不匹配错误:
def update(array): Arr = ndarray2carray(array,"b") winDLL.window_show.argtypes = [ct.POINTER(ct.POINTER(ct.c_ubyte))] winDLL.window_show.restype = None winDLL.window_show(ct.pointer(Arr)) return
报错:ctypes.ArgumentError: argument 1: <class 'TypeError'>: expected LP_LP_c_ubyte instance instead of LP_c_ubyte_Array_2073600
之后再次使用type(pArr)作为argtypes,仍出现访问违规。
第三次尝试:参考Stack Overflow方案
使用该方案后依然出现访问违规错误:
def update(array): # ubyte pointers uPtr = ct.POINTER(ct.c_ubyte) uPtrPtr = ct.POINTER(uPtr) # initialize dll function winDLL.window_show.argtypes = [uPtrPtr] winDLL.window_show.restypes = ct.c_ubyte # convert np array into c array print(array) ct_arr = np.ctypeslib.as_ctypes(array) ptr_arr = uPtr * ct_arr._length_ ct_ptr = ct.cast(ptr_arr(*(ct.cast(row, uPtr) for row in ct_arr)), uPtrPtr) # pass into the function winDLL.window_show(ct_ptr) return
请问是否有其他解决方法?或是DLL本身的问题?感谢解答!
内容的提问来源于stack exchange,提问作者yihsin
相关产品推荐
相关产品推荐

