我花了几个小时,但仍然不明白为什么在C#中使用Interop时,从Hid.dll调用HidP_GetButtonCaps例程失败(为什么)。>
我正在列出设备并尝试获取ButtonCaps等。但是,当调用HidP_GetButtonCaps(或HidP_GetValueCaps)时,extern函数将返回HIDP_STATUS_INVALID_REPORT_TYPE错误。而且我只是不明白...此例程中的报告类型参数是一个枚举值,它怎么会失败???
这里是一些代码摘录。我不会放所有东西,因为它很长。当然,如果需要提供更多详细信息,我将其添加。
代码中有注释“ // REMARK”,这是注释内容:-备注1:hidDevice对象参数来自另一种方法。我知道在调试模式下检查内容时,“ DevicePath”,“ preparsedData”和“ ButtonCaps”字段的内容正确。-备注2:这是我遇到的问题。我已经尝试了3种不同的参数方式:使用HIDP_REPORT_TYPE对象,直接使用HIDP_REPORT_TYPE.HidP_Input或“ 0”,它没有任何区别...
非常感谢您的帮助。
结构,常量,枚举...:
public enum HIDP_REPORT_TYPE : ushort { HidP_Input, HidP_Output, HidP_Feature } public struct ButtonCapsRange { public ushort UsageMin; public ushort UsageMax; public ushort StringMin; public ushort StringMax; public ushort DesignatorMin; public ushort DesignatorMax; public ushort DataIndexMin; public ushort DataIndexMax; } public struct ButtonCapsNotRange { public ushort Usage; public ushort Reserved1; public ushort StringIndex; public ushort Reserved2; public ushort DesignatorIndex; public ushort Reserved3; public ushort DataIndex; public ushort Reserved4; } [StructLayout(LayoutKind.Explicit)] public struct HIDP_BUTTON_CAPS { [FieldOffset(0)] public ushort UsagePage; [FieldOffset(2)] public byte ReportID; [FieldOffset(3)] public bool IsAlias; [FieldOffset(4)] public ushort BitField; [FieldOffset(6)] public ushort LinkCollection; [FieldOffset(8)] public ushort LinkUsage; [FieldOffset(10)] public ushort LinkUsagePage; [FieldOffset(12)] public bool IsRange; [FieldOffset(13)] public bool IsStringRange; [FieldOffset(14)] public bool IsDesignatorRange; [FieldOffset(15)] public bool IsAbsolute; [FieldOffset(16)] public uint[] Reserved; [FieldOffset(16 + 10 * 4)] public ButtonCapsRange Range; [FieldOffset(16 + 10 * 4)] public ButtonCapsNotRange NotRange; } public struct HID_DEVICE { public String DevicePath; public IntPtr pHidDevice; // A file handle to the hid device. public bool OpenedForRead; public bool OpenedForWrite; public bool OpenedOverlapped; public bool OpenedExclusive; public IntPtr Ppd; // The opaque parser info describing this device public HIDP_CAPS Caps; // The Capabilities of this hid device. public HIDD_ATTRIBUTES Attributes; public byte[] pInputReportBuffer; public HID_DATA[] InputData; // array of hid data structures public ulong InputDataLength; // Num elements in this array. public HIDP_BUTTON_CAPS[] pInputButtonCaps; public HIDP_VALUE_CAPS[] pInputValueCaps; public byte[] pOutputReportBuffer; public HID_DATA[] pOutputData; public ulong OutputDataLength; public HIDP_BUTTON_CAPS[] pOutputButtonCaps; public HIDP_VALUE_CAPS[] pOutputValueCaps; public byte[] pFeatureReportBuffer; public HID_DATA[] pFeatureData; public ulong FeatureDataLength; public HIDP_BUTTON_CAPS[] pFeatureButtonCaps; public HIDP_VALUE_CAPS[] pFeatureValueCaps; }
外部方法:
[DllImport("hid.dll", SetLastError = true)] [SecurityPermission(SecurityAction.Assert, Unrestricted = true)] static extern int HidP_GetButtonCaps([MarshalAs(UnmanagedType.U2)] HIDP_REPORT_TYPE ReportType, ref HIDP_BUTTON_CAPS[] ButtonCaps, ref ushort ButtonCapsLength, IntPtr PreparsedData);
方法调用:
private static bool FillDeviceInfo(ref HID_DEVICE hidDevice)
{
//REMARK 1
ulong numValues;
ushort numCaps;
HIDP_BUTTON_CAPS[] buttonCaps;
HIDP_VALUE_CAPS[] valueCaps;
HID_DATA[] data;
ulong i;
ushort usage;
uint dataIdx;
hidDevice.pInputReportBuffer = new byte[hidDevice.Caps.InputReportByteLength];
buttonCaps = new HIDP_BUTTON_CAPS[hidDevice.Caps.NumberInputButtonCaps];
//for(int a=0;a<buttonCaps.Length ;a++)
// buttonCaps[a].Reserved = new uint[10];
hidDevice.pInputButtonCaps = buttonCaps;
valueCaps = new HIDP_VALUE_CAPS[hidDevice.Caps.NumberInputValueCaps];
hidDevice.pInputValueCaps = valueCaps;
numCaps = hidDevice.Caps.NumberInputButtonCaps;
if (numCaps > 0)
{
//REMARK 2
HIDP_REPORT_TYPE reportType = HIDP_REPORT_TYPE.HidP_Input;
int val = (HidP_GetButtonCaps(reportType, ref buttonCaps, ref numCaps, hidDevice.Ppd));
if (HIDP_STATUS_SUCCESS != val)
{
return false;
}
}
//other stuff and retur true at end
}
我花了几个小时,但仍然不明白为什么在C#中使用Interop时,调用HidP_GetButtonCaps例程(从hid.dll)失败。我正在列出设备并尝试获取ButtonCaps等。 ...
确定发现问题...经常是愚蠢的错误。
我遇到了同样的例外。我认为在CLR中尝试通过联合将数据自动编组到结构时存在问题。也许。我写了自己的拆包方法,似乎已经解决了问题。