C# 将DeviceIoControl调用返回值结构从C映射到C时出现问题#
我正在修改一些查询设备树并报告设备功能的代码,特别是USB端口及其速度。我正在从DeviceIoControl调用中获取_USB_节点_连接_信息_EX对象,但它错误地将USB 3.0报告为高速。进一步的研究表明,我需要从DeviceIoControl获取_USB_NODE_CONNECTION_INFORMATION_EX_V2 struct以适应USB 3.0。我试图将新结构从C映射到C,但对于如何处理作为新(ish)USB节点连接信息EX V2结构成员存在的两个C联合,我有点困惑 我在大学里得了C,比如说,差不多20年前。我职业生涯的大部分时间都在Powerbuilder(别笑,那是很久以前的事了)、Java(别笑,那是很久以前的事了),但主要是C。有哪位C大师能帮我将这些带并集的结构映射到C#结构中,并可能给我一个如何将它们编组的线索?注意,我已经映射了USB\uNode\uConnection\uEx\uV2,但不知道如何处理USB\uProtocols和USB\uNode\uConnection\uEx\uV2\uFlags结构。最好将_USB_PROTOCOLS结构映射到C#Flags枚举中,这样我也可以使用按位and和or 下面的代码显示了注释掉的C typedef和我在C#中对应的结构(未注释和…嗯,未完成:()。提前感谢大家C# 将DeviceIoControl调用返回值结构从C映射到C时出现问题#,c#,c,winapi,C#,C,Winapi,我正在修改一些查询设备树并报告设备功能的代码,特别是USB端口及其速度。我正在从DeviceIoControl调用中获取_USB_节点_连接_信息_EX对象,但它错误地将USB 3.0报告为高速。进一步的研究表明,我需要从DeviceIoControl获取_USB_NODE_CONNECTION_INFORMATION_EX_V2 struct以适应USB 3.0。我试图将新结构从C映射到C,但对于如何处理作为新(ish)USB节点连接信息EX V2结构成员存在的两个C联合,我有点困惑 我在大学
//typedef struct _USB_NODE_CONNECTION_INFORMATION_EX_V2
//{
// ULONG ConnectionIndex;
// ULONG Length;
// USB_PROTOCOLS SupportedUsbProtocols;
// USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags;
//}
//USB_NODE_CONNECTION_INFORMATION_EX_V2, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2;
struct USB_NODE_CONNECTION_INFORMATION_EX_V2
{
public int ConnectionIndex;
public int Length;
public USB_PROTOCOLS SupportedUsbProtocols;
public USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags;
}
//typedef union _USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS {
// ULONG ul;
// struct {
// ULONG DeviceIsOperatingAtSuperSpeedOrHigher :1;
// ULONG DeviceIsSuperSpeedCapableOrHigher :1;
// ULONG ReservedMBZ :30;
// };
//}
//USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS, * PUSB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS;
struct USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS
{
}
//typedef union _USB_PROTOCOLS {
// ULONG ul;
// struct {
// ULONG Usb110 :1;
// ULONG Usb200 :1;
// ULONG Usb300 :1;
// ULONG ReservedMBZ :29;
// };
//}
//USB_PROTOCOLS, * PUSB_PROTOCOLS;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct USB_PROTOCOLS
{
}
USB_协议
是一个联合结构,它只是包装一个32位整数,其中位0是Usb110,位1是Usb200,位2是Usb300。定义如下:
public struct USB_PROTOCOLS
{
UInt32 protocols;
public bool Usb110 { get { return (this.protocols & 0x01) == 0x01; } }
public bool Usb200 { get { return (this.protocols & 0x02) == 0x02; } }
public bool Usb300 { get { return (this.protocols & 0x04) == 0x04; } }
}
USB\u节点\u连接\u信息\u EX\u V2\u标志的故事大致相同,但为了完整性:
public struct USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS
{
UInt32 flags;
public bool DeviceIsOperatingAtSuperSpeedOrHigher
{
get { return (this.flags & 0x01) == 0x01; }
}
public bool DeviceIsSuperSpeedCapableOrHigher
{
get { return (this.flags & 0x02) == 0x02; }
}
}
或者,您可以使用Flags
属性将这两个属性都定义为枚举
[Flags]
public enum USB_PROTOCOLS : uint
{
Usb110 = 0x01,
Usb200 = 0x02,
Usb300 = 0x04,
}
[Flags]
public enum USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS : uint // nice short type name
{
DeviceIsOperatingAtSuperSpeedOrHigher = 0x01,
DeviceIsSuperSpeedCapableOrHigher = 0x02,
}
或者,由于三个选项优于两个选项,您还可以将第一个结构的定义更改为:
struct USB_NODE_CONNECTION_INFORMATION_EX_V2
{
public int ConnectionIndex;
public int Length;
public uint SupportedUsbProtocols;
public uint Flags;
}
自己动手做一些小动作
<>我是如何做到的?我在VisualStudio中打开了一个C++控制台应用程序,并编写了以下程序,然后在调试器中逐步通过:
#include <usbioctl.h>
int size = sizeof(USB_PROTOCOLS); // size = 4
USB_PROTOCOLS proto = { 0 };
proto.Usb110 = 1;
unsigned int val = *((unsigned int*)(&proto)); // val = 1
proto.Usb110 = 0;
proto.Usb200 = 1;
val = *((unsigned int*)(&proto)); // val = 2
proto.Usb200 = 0;
proto.Usb300 = 1;
val = *((unsigned int*)(&proto)); // val = 4
size = sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS); // size = 4
USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS flags = { 0 };
flags.DeviceIsOperatingAtSuperSpeedOrHigher = 1;
val = *((unsigned int*)(&flags)); // val = 1
flags.DeviceIsOperatingAtSuperSpeedOrHigher = 0;
flags.DeviceIsSuperSpeedCapableOrHigher = 1;
val = *((unsigned int*)(&flags)); // val = 2
#包括
int size=sizeof(USB_协议);//size=4
USB_协议协议proto={0};
proto.Usb110=1;
unsigned int val=*((unsigned int*)(&proto));//val=1
proto.Usb110=0;
proto.Usb200=1;
val=*((无符号int*)(&proto));//val=2
proto.Usb200=0;
proto.Usb300=1;
val=*((无符号int*)(&proto));//val=4
size=sizeof(USB_节点_连接_信息_EX_V2_标志);//size=4
USB_节点_连接_信息_EX_V2_标志={0};
flags.DeviceIsOperatingAtSuperSpeedOrHigher=1;
val=*((unsigned int*)(&flags));//val=1
flags.DeviceIsOperatingAtSuperSpeedOrHigher=0;
flags.deviceissuperspeedcapable或更高版本=1;
val=*((unsigned int*)(&flags));//val=2