You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:07:41