C++ C++;-64位上SP_DEVINFO_列表_详细信息_数据的大小

C++ C++;-64位上SP_DEVINFO_列表_详细信息_数据的大小,c++,data-structures,msdn,C++,Data Structures,Msdn,在64位上,的大小为560。不是应该是554吗 typedef struct _SP_DEVINFO_LIST_DETAIL_DATA_W { DWORD cbSize; GUID ClassGuid; HANDLE RemoteMachineHandle; WCHAR RemoteMachineName[SP_MAX_MACHINENAME_LENGTH]; } SP_DEVINFO_LIST_DETAIL_DATA, *PSP_DEVINFO_LIST_DETAIL_

在64位上,的大小为560。不是应该是554吗

typedef struct _SP_DEVINFO_LIST_DETAIL_DATA_W {
  DWORD  cbSize;
  GUID   ClassGuid;
  HANDLE RemoteMachineHandle;
  WCHAR  RemoteMachineName[SP_MAX_MACHINENAME_LENGTH];
} SP_DEVINFO_LIST_DETAIL_DATA, *PSP_DEVINFO_LIST_DETAIL_DATA;
cbSize为4,类GUID为16,RemoteMachineHandle为8(64位),RemoteMachineName为2*(260+3)(SP\u MAX\u MACHINENAME\u长度为最大路径+3)


所以,4+16+8+2*263=554。为什么sizeof(_SP_DEVINFO_LIST_DETAIL_DATA_W)返回560?

我猜填充是为了满足某些成员的对齐要求。我不熟悉这些类型,因此无法解释这种结构的对齐方式


如果您真的想以最有效的方式打包结构,可以按大小(递减)排序成员。编译器通常不允许对成员重新排序。

我猜填充是为了满足某些成员的对齐要求。我不熟悉这些类型,因此无法解释这种结构的对齐方式


如果您真的想以最有效的方式打包结构,可以按大小(递减)排序成员。编译器通常不允许对成员进行重新排序。

您忽略了对齐字段的要求,这对于确保处理器可以有效访问字段非常重要。当您以x64为目标时,句柄类型为64位8字节。因此,RemoteMachineHandle成员与8的倍数的偏移对齐。将其从偏移量20移动到偏移量24,下一个偏移量可被8整除。额外的4个字节是填充的,未使用

这使得结构大小为4+16+4+8+2*263=558字节

还有一个问题-此结构的数组会使句柄再次错位。索引1处的元素的句柄位于偏移量558+4+16+4=582处。如果不是8的倍数,则该构件将再次错位

因此,编译器会在结构的末尾添加额外的2个字节的填充,因此结构的总大小是8的倍数。因此:

Offset  Size    Member
   0      4     cbSize
   4     16     ClassGuid
  20      4     -
  24      8     RemoteMachineHandle
  32    526     RemoteMachineName
 558      2     -
-------------
        560

您忽略了对齐字段的要求,这对于确保处理器可以高效地访问字段非常重要。当您以x64为目标时,句柄类型为64位8字节。因此,RemoteMachineHandle成员与8的倍数的偏移对齐。将其从偏移量20移动到偏移量24,下一个偏移量可被8整除。额外的4个字节是填充的,未使用

这使得结构大小为4+16+4+8+2*263=558字节

还有一个问题-此结构的数组会使句柄再次错位。索引1处的元素的句柄位于偏移量558+4+16+4=582处。如果不是8的倍数,则该构件将再次错位

因此,编译器会在结构的末尾添加额外的2个字节的填充,因此结构的总大小是8的倍数。因此:

Offset  Size    Member
   0      4     cbSize
   4     16     ClassGuid
  20      4     -
  24      8     RemoteMachineHandle
  32    526     RemoteMachineName
 558      2     -
-------------
        560

我尝试使用SetupDiGetDeviceInfoListDetail,但也得到了错误的大小。最后我找到了解决办法

这是结构的定义

typedef struct _SP_DEVINFO_LIST_DETAIL_DATA {
  DWORD  cbSize;
  GUID   ClassGuid;
  HANDLE RemoteMachineHandle;
  TCHAR  RemoteMachineName[SP_MAX_MACHINENAME_LENGTH];
} SP_DEVINFO_LIST_DETAIL_DATA, *PSP_DEVINFO_LIST_DETAIL_DATA;
在setupapi.h中

#define SP_MAX_MACHINENAME_LENGTH   (MAX_PATH + 3)

[StructLayout(LayoutKind.Sequential,Pack = 1, CharSet = CharSet.Ansi)]
    public struct  SP_DEVINFO_LIST_DETAIL_DATA
    {
        public uint cbSize;
        public Guid classGuid;
        public int RemoteMachineHandle;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 263)]public string RemoteMachineName;

    };

我尝试使用SetupDiGetDeviceInfoListDetail,但也得到了错误的大小。最后我找到了解决办法

这是结构的定义

typedef struct _SP_DEVINFO_LIST_DETAIL_DATA {
  DWORD  cbSize;
  GUID   ClassGuid;
  HANDLE RemoteMachineHandle;
  TCHAR  RemoteMachineName[SP_MAX_MACHINENAME_LENGTH];
} SP_DEVINFO_LIST_DETAIL_DATA, *PSP_DEVINFO_LIST_DETAIL_DATA;
在setupapi.h中

#define SP_MAX_MACHINENAME_LENGTH   (MAX_PATH + 3)

[StructLayout(LayoutKind.Sequential,Pack = 1, CharSet = CharSet.Ansi)]
    public struct  SP_DEVINFO_LIST_DETAIL_DATA
    {
        public uint cbSize;
        public Guid classGuid;
        public int RemoteMachineHandle;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 263)]public string RemoteMachineName;

    };

衬垫。出于速度原因,允许编译器在成员之间添加任意可用空间。在编译器外部,即通过共享库调用WinAPI函数时,会返回相同大小的空间。为什么人们总是认为他们知道这一点?并且拒绝搜索它?几乎每天都有人问这个问题。出于速度原因,编译器可以在成员之间添加任意可用空间。在编译器外部,即通过共享库调用WinAPI函数时,会返回相同的大小。为什么人们总是认为他们知道这一点?并拒绝搜索它?几乎每天都有人问这个问题:(关于正在使用的对齐填充,您是对的,但是您确定填充是在
ClassGuid
之后添加的,而不是在
cbSize
之后添加的吗?),这会将
ClassGuid
对齐到8字节的偏移量,而不会影响其余成员的对齐。是的,我确定,您可以用offsetof()检查它。)宏。GUID是一种隐藏的结构,它最大的成员类型是Data1,一个长的,因此只有4的对齐要求。
GUID
是显式字节对齐的,通过在所有环境中强制其成员之间没有填充来确保其16字节的大小。在ot中使用
GUID
值时,这不会影响对齐她的结构。不,它与4对齐。你自己用一个带有char、GUID和offsetof()的结构试试看宏。您对使用对齐填充的看法是正确的,但是您确定填充是在
ClassGuid
之后添加的,而不是在
cbSize
之后添加的吗?这将使
ClassGuid
对齐到8字节的偏移量,而不会影响其余成员的对齐。是的,我确定,您可以用offsetof()检查它宏。GUID是一种隐藏的结构,它最大的成员类型是Data1,一个长的,因此只有4的对齐要求。
GUID
是显式字节对齐的,通过在所有环境中强制其成员之间没有填充来确保其16字节的大小。在ot中使用
GUID
值时,这不会影响对齐她的结构。不,它与4对齐。你自己用一个带有char和GUID的结构和offsetof()宏试试看。