Winapi HidD_SetFeature()工作得很好,HidD_GetFeature()失败并出现错误(23)。这是什么原因造成的?

Winapi HidD_SetFeature()工作得很好,HidD_GetFeature()失败并出现错误(23)。这是什么原因造成的?,winapi,usb,hid,Winapi,Usb,Hid,我正在开发一个USB设备作为标准的HID键盘,在报告描述符中添加了一个8字节的功能报告;我正在编写一个主机应用程序来配置设备。我正在尝试调整这个奇妙的函数,以利用hid.dll中的HidD_GetFeature()函数 在我开始发布c#代码之前,我要说的是,我已经使用SimpleHidWrite实用程序成功地测试了我的固件,并使用Get和Set功能命令,因此我非常确信这不是问题所在 HidD_SetFeature()函数包装在HidLibrary API中,效果非常好。我可以向设备写入8个字节,

我正在开发一个USB设备作为标准的HID键盘,在报告描述符中添加了一个8字节的功能报告;我正在编写一个主机应用程序来配置设备。我正在尝试调整这个奇妙的函数,以利用hid.dll中的HidD_GetFeature()函数

在我开始发布c#代码之前,我要说的是,我已经使用SimpleHidWrite实用程序成功地测试了我的固件,并使用Get和Set功能命令,因此我非常确信这不是问题所在

HidD_SetFeature()函数包装在HidLibrary API中,效果非常好。我可以向设备写入8个字节,并且我已经使用该工具验证了它们是否正确存储。然而,我无法使用HidD_GetFeature()将这些字节拉回来,我很困惑为什么

以下是我认为相关的细节

首先,使用以下值将CreateFile调用内置到库中:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    internal static IntPtr CreateFile(
        string lpFileName,
        uint dwDesiredAccess,
        int dwShareMode,
        ref HidLibrary.NativeMethods.SECURITY_ATTRIBUTES lpSecurityAttributes,
        int dwCreationDisposition,
        int dwFlagsAndAttributes,
        int hTemplateFile);
其中(使用测试视频/pid):

导入定义:

[DllImport("hid.dll", SetLastError = true)]
    static internal extern bool HidD_GetFeature(IntPtr hidDeviceObject, ref byte[] lpReportBuffer, int reportBufferLength);
最后,我创建的API方法当前在HidD_GetFeature()调用中失败,错误为23(error_CRC):

public bool ReadFeatureData(字节reportId,out字节[]数据)
{

如果(_deviceCapabilities.featurereportbytellength,我认为这个声明可能是问题所在

[DllImport("hid.dll", SetLastError = true)]
    static internal extern bool HidD_GetFeature(IntPtr hidDeviceObject, ref byte[] lpReportBuffer, int reportBufferLength);

尝试将lpReportBufferref参数更改为out,或者完全忽略它。

是,您的声明就是问题所在

使用:


否:ref或out

ref
更改为
out
不起作用,但简单地忽略它就可以了。谢谢!
    public bool ReadFeatureData(byte reportId, out byte[] data)
    {
        if (_deviceCapabilities.FeatureReportByteLength <= 0)
        {
            data = new byte[0];
            return false;
        }
        // FeatureReportByteLength returns 9 (byte 0 is the report id and 8 bytes for the actual report length)
        data = new byte[_deviceCapabilities.FeatureReportByteLength];

        //yields a 9-byte array
        var buffer = this.CreateFeatureInputBuffer(); 
        buffer[0] = reportId;

        IntPtr hidHandle = IntPtr.Zero;
        bool success = false;
        try
        {
            // Performs the CreateFile call above resulting in an IntPtr handle
            hidHandle = OpenDeviceIO(_devicePath, NativeMethods.ACCESS_NONE);

            success = NativeMethods.HidD_GetFeature(hidHandle, ref buffer, buffer.Length);
            // at this point, success is false, and buffer has gone from 9 bytes to 1

            if(success)
            {
                Array.Copy(buffer, 0, data, 0, Math.Min(data.Length, _deviceCapabilities.FeatureReportByteLength));
            }
            else
            {
                //Yes, i know casting to a byte isn't good here; it's dirty but helping me debug for now
                data[0] = (byte)Marshal.GetLastWin32Error(); //returns 23 (verified, actual) - ERROR_CRC
            }

        }
        catch (Exception exception)
        {
            throw new Exception(string.Format("Error accessing HID device '{0}'.", _devicePath), exception);
        }
        finally
        {
            if (hidHandle != IntPtr.Zero)
                CloseDeviceIO(hidHandle);
        }

        return success;
    }
[DllImport("hid.dll", SetLastError = true)]
    static internal extern bool HidD_GetFeature(IntPtr hidDeviceObject, ref byte[] lpReportBuffer, int reportBufferLength);
    [DllImport("hid.dll", SetLastError = true)]
    protected static extern bool HidD_GetFeature(   IntPtr hDevInfo,
                                                    Byte[] lpReportBuffer, 
                                                    Int32 ReportBufferLength);