使用异步WinUSB IO时WinUsb_WritePipe返回错误997的原因?
解决WinUsb_WritePipe返回FALSE且GetLastError=997的问题
错误997对应的是重叠I/O操作正在进行中,你的代码问题出在OVERLAPPED结构关联的事件处理上:
问题根源
你创建的是手动重置事件(CreateEvent第二个参数为TRUE),这类事件在被触发后会持续保持触发状态,不会自动重置。在循环流程中,WinUsb_GetOverlappedResult等待操作完成后,事件仍处于触发状态,导致下一次调用WinUsb_WritePipe时,系统误判前一次重叠I/O还在执行,从而返回错误997。
修复方案
方案1:改用自动重置事件(推荐)
将CreateEvent的第二个参数改为FALSE,这样事件在被WinUsb_GetOverlappedResult等待触发后,会自动重置为未触发状态:
OVERLAPPED ovr = { 0 }; ovr.hEvent = CreateEvent(NULL, FALSE, FALSE, "USBWrite"); // 第二个参数改为FALSE ... while( ... ) { WinUsb_GetOverlappedResult( winusbhandle, &ovr, &NumberOfBytesTransferred, TRUE); WinUsb_WritePipe(winusbhandle, 0x01, usb_out_buffer, sizeof(usb_out_buffer), &bytesWritten, &ovr); }
方案2:手动重置事件状态
如果必须使用手动重置事件,在WinUsb_GetOverlappedResult之后、下一次WinUsb_WritePipe之前,调用ResetEvent重置事件状态:
while( ... ) { WinUsb_GetOverlappedResult( winusbhandle, &ovr, &NumberOfBytesTransferred, TRUE); ResetEvent(ovr.hEvent); // 重置事件为未触发状态 WinUsb_WritePipe(winusbhandle, 0x01, usb_out_buffer, sizeof(usb_out_buffer), &bytesWritten, &ovr); }
额外注意事项
- 若
WinUsb_WritePipe返回FALSE但GetLastError()是ERROR_IO_PENDING,这是正常现象,表示重叠I/O已在后台启动,后续通过WinUsb_GetOverlappedResult等待完成即可。 - 确保事件句柄在整个循环周期内保持有效,不要提前关闭。
内容的提问来源于stack exchange,提问作者Charles Lohr
相关产品推荐
相关产品推荐

