如何将memoryview传入win32.ReadFile实现Pyserial的readinto函数?
解决Windows下pyserial readinto()中memoryview无法传入ReadFile的问题
要让win32.ReadFile()接受memoryview,核心是将memoryview转换为ctypes可识别的底层内存指针/缓冲区对象,这样就能直接操作共享内存区域,完全避免额外拷贝。
关键修改步骤
- 确保memoryview有效性:传入的
buf必须是连续、可写的字节类型memoryview(串口读取字节流,且需要写入共享内存)。 - 转换为ctypes兼容对象:使用
ctypes.from_buffer()将memoryview包装成ctypes数组,直接映射底层内存,让ReadFile可以直接操作。
修改后的完整代码
def serial_read_into(serial_object, buf, size) -> int: if not serial_object.is_open: raise PortNotOpenError() if size == 0: return 0 win32.ResetEvent(serial_object._overlapped_read.hEvent) flags = win32.DWORD() comstat = win32.COMSTAT() if not win32.ClearCommError(serial_object._port_handle, ctypes.byref(flags), ctypes.byref(comstat)): raise SerialException("ClearCommError failed ({!r})".format(ctypes.WinError())) length = min(comstat.cbInQue, size) if serial_object.timeout == 0 else size if length == 0: return 0 # 核心修改:将memoryview转换为ctypes兼容缓冲区 if isinstance(buf, memoryview): if buf.format != 'B' or not buf.writeable: raise ValueError("buf必须是可写的字节类型memoryview") c_buf = ctypes.from_buffer(buf) else: c_buf = buf rc = win32.DWORD() read_ok = win32.ReadFile( serial_object._port_handle, c_buf, length, # 改用计算后的length,避免超出实际可用数据或缓冲区大小 ctypes.byref(rc), ctypes.byref(serial_object._overlapped_read)) if not read_ok and win32.GetLastError() not in (win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING): raise SerialException("ReadFile failed ({!r})".format(ctypes.WinError())) result_ok = win32.GetOverlappedResult( serial_object._port_handle, ctypes.byref(serial_object._overlapped_read), ctypes.byref(rc), True) if not result_ok: if win32.GetLastError() != win32.ERROR_OPERATION_ABORTED: raise SerialException("GetOverlappedResult failed ({!r})".format(ctypes.WinError())) return rc.value
额外优化说明
- 将原代码中
ReadFile的size参数改为length,避免在超时非零场景下,请求字节数超出实际可用数据或内存视图的大小。 - 增加
memoryview类型校验,提前抛出明确错误,避免后续ctypes调用崩溃。
原理说明
ctypes.from_buffer()直接创建指向memoryview底层内存的ctypes对象,不会产生任何内存拷贝,完全契合你使用multiprocessing.SharedMemory的初衷——让串口数据直接写入共享内存区域,无需中转。
内容的提问来源于stack exchange,提问作者user765269
相关产品推荐
相关产品推荐

