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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:05:12