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

使用ctypes调用DLL的search_devices函数传指针触发访问违例问题

问题根因

这个问题是Python侧传参不符合接口要求和DLL本身存在严重实现缺陷共同导致的:

  • 首先是Python传参错误:你初始化的serial_list = ctypes.c_char_p()是一个值为NULL的字符指针,传入byref(serial_list)相当于给函数传了一个指向NULL地址的二级指针,完全不符合接口要求。对照厂商提供的C示例可以看到,调用方需要提前分配好两级内存:第一级是长度128的字符指针数组,第二级是数组里每个指针都要指向一块至少8字节的可写内存,用来存单个设备的序列号。传入空指针后,函数尝试向NULL地址写入数据,直接触发首次运行的访问违例错误。
  • DLL本身的缺陷是导致设备锁死、返回值异常的核心原因,具体问题包括:
    1. 接口定义与实现不匹配:头文件声明第一个参数是char**(字符串数组,用于存储多个独立的序列号字符串),但实际实现逻辑是把所有设备序列号拼成一个长字符串,直接strcpy到第一个参数指向的地址,根本没有按字符串数组的结构给每个指针赋值,就算是厂商自己提供的C示例代码,按这个实现运行也会触发内存越界。
    2. 资源清理逻辑完全失效:在libusb初始化失败、获取设备列表失败的异常分支中,没有正常关闭libusb上下文、释放已打开的设备句柄,甚至出现了“没拿到设备列表就提前调用释放设备列表接口”的错误逻辑。第一次运行触发访问违例时,代码执行到一半崩溃,已打开的USB设备句柄、libusb会话没有被正常释放,会在系统层面锁定设备,导致厂商GUI无法识别。
    3. 返回值和输出参数逻辑混乱:代码中内存分配失败、正常执行完成两个场景都返回0,和文档描述的“失败返回负数”的规则矛盾;异常分支下不会给*dev_count(设备数输出参数)赋值,所以你第一次崩溃时看到num_devices停留在初始值99,后续运行因为libusb之前异常退出没重新初始化,设备数被置为0。
    4. 内存操作存在溢出风险:内部拼接序列号的缓冲区只分配了160字节,没有做剩余长度校验,连接超过17个设备就会触发堆内存越界。
临时适配方案

按照厂商C示例的内存规则,在Python侧提前分配符合要求的缓冲区,不要传入空指针,参考代码:

import ctypes

usb_dll = ctypes.CDLL(r"path_to_dll")
usb_dll.search_devices.argtypes = [ctypes.POINTER(ctypes.c_char_p), ctypes.POINTER(ctypes.c_uint32)]
usb_dll.search_devices.restype = ctypes.c_long

MAX_DEVICE = 128
SERIAL_BUF_LEN = 8
# 分配一级指针数组
serial_ptr_arr = (ctypes.c_char_p * MAX_DEVICE)()
# 给每个指针分配独立的可写缓冲区,持有引用避免被GC回收
buf_holder = []
for idx in range(MAX_DEVICE):
    buf = ctypes.create_string_buffer(SERIAL_BUF_LEN)
    buf_holder.append(buf)
    serial_ptr_arr[idx] = ctypes.cast(buf, ctypes.c_char_p)

dev_count = ctypes.c_uint32(0)
status = usb_dll.search_devices(serial_ptr_arr, ctypes.byref(dev_count))

# 读取识别到的序列号
result_serials = []
for i in range(dev_count.value):
    result_serials.append(serial_ptr_arr[i].decode("ascii"))

注意:该适配是基于厂商公开的接口约定编写,如果你拿到的DLL是贴出的UsbSearchDevicesLV的实现版本(把所有序列号拼成单字符串写入),说明DLL版本和头文件、示例代码不匹配,必须找厂商索取版本匹配的DLL和正确的接口文档,否则内存越界问题无法彻底解决。

内容的提问来源于stack exchange,提问作者ttshaw1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:54:36