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

开发C# Joy-Con库时FileStream.BeginRead抛出Win32错误1784求助

解决Joy-Con HID通信中Win32错误1784的问题

我之前在做C# HID设备通信项目时刚好踩过这个Win32 1784(缓冲区无效)的坑,结合你开发Joy-Con库的场景,大概率是输入报告缓冲区大小不匹配导致的——这也是HID设备交互里最容易忽略的细节。

核心问题分析

你提到其他项目用49字节的报告长度,但Joy-Con的输入报告长度并不是固定值:它会根据设备当前的工作模式(比如配对模式、常规操作模式)或者你发送的初始化命令发生变化。直接沿用别人的数值,很可能和当前设备实际要求的缓冲区大小不匹配,触发系统的参数校验错误。

具体解决步骤

  1. 动态获取Joy-Con的真实输入报告长度
    不要硬编码报告长度,通过Windows HID API动态获取才是可靠方案:

    • 先用HidD_GetPreparsedData获取设备的预解析数据
    • 再调用HidP_GetCaps获取HIDP_CAPS结构体,其中的InputReportByteLength字段就是设备要求的输入报告字节数
      示例代码片段(C# P/Invoke部分):
    [DllImport("hid.dll", SetLastError = true)]
    private static extern bool HidD_GetPreparsedData(IntPtr hidDeviceObject, out IntPtr preparsedData);
    
    [DllImport("hid.dll", SetLastError = true)]
    private static extern HidPStatus HidP_GetCaps(IntPtr preparsedData, out HIDP_CAPS caps);
    
    // 定义HIDP_CAPS结构体
    [StructLayout(LayoutKind.Sequential)]
    public struct HIDP_CAPS
    {
        public ushort Usage;
        public ushort UsagePage;
        public ushort InputReportByteLength;
        // 其他字段省略...
    }
    
    // 获取报告长度的核心逻辑
    if (HidD_GetPreparsedData(deviceHandle, out var preparsedData))
    {
        if (HidP_GetCaps(preparsedData, out var caps) == HidPStatus.Success)
        {
            int inputReportLength = caps.InputReportByteLength;
            // 保存这个长度用于后续缓冲区创建
        }
        HidD_FreePreparsedData(ref preparsedData); // 务必释放资源
    }
    
  2. 保证BeginRead的缓冲区大小完全匹配
    用上面获取到的inputReportLength创建读取缓冲区,大小必须和设备要求的完全一致,不能多也不能少:

    byte[] readBuffer = new byte[inputReportLength];
    // 正确调用BeginRead
    stream.BeginRead(readBuffer, 0, readBuffer.Length, OnReadCompleted, stream);
    
  3. 检查FileStream的创建参数
    确认创建FileStream时的参数配置合理,建议使用以下设置:

    FileStream stream = new FileStream(devicePath, FileAccess.ReadWrite, 
        inputReportLength, FileShare.ReadWrite, FileOptions.Asynchronous);
    

    这里的第三个参数(缓冲区大小)最好和输入报告长度保持一致,避免额外的内存适配问题。

额外注意事项

  • Joy-Con刚连接时可能处于配对模式,此时报告长度和常规操作模式不同,你需要先发送初始化命令(比如设置输入报告模式的指令)切换到工作模式,再获取正确的报告长度。
  • 调用HID API后一定要记得释放资源(比如预解析数据、设备句柄),避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:57:05