我需要使用这个Kernel32结构:NUMA_NODE_RELATIONSHIP
但保留字段声明为:BYTE Reserved[20];
要正确地声明结构,有没有比声明更好的方法:
public struct NUMA_NODE_RELATIONSHIP
{
public UInt16 NodeNumber;
public BYTE Reserved1;
public BYTE Reserved2;
...
public BYTE Reserved20;
public GROUP_AFFINITY GroupMask;
}
或使用:
[StructLayout(LayoutKind.Explicit)]
public struct NUMA_NODE_RELATIONSHIP2
{
[FieldOffset(0)]
public UInt16 NodeNumber;
// [FieldOffset(2)] // **
// public byte Reserved;
[FieldOffset(22)]
public GROUP_AFFINITY GroupMask;
}
**我不确定我的代码是否正常......这里FieldOffset是OS字大小(32或64位)的字节偏移还是倍数? WIN32 API pad是否对齐struct字段,如果是,如何?如果两者都填充或两者都没有填充,我很好,否则我的代码会被窃听。这不是我的主要问题。那个插入只是提到我的代码不一定按照它编写的方式工作。我的主要问题是这一个:
声明带有数组的pinvoke结构的最佳方法是什么? 我想知道两者是否合适,哪一个是首选和/或是否有更好的方式来声明该结构,因为我使用了添加工件,这使得它很难写和/或更难理解。
答案 0 :(得分:1)
WinAPI以大小的自然大小对齐大多数小类,因此WORD为16位,DWORD为32位。 BYTE是一个字节,不对齐。在需要的地方插入填充以实现下一个成员的正确对齐。
这里的诀窍是GROUP_AFFINITY
的对象。我认为这是2个字节,因为它的所有成员都是WORD
。
我认为它的2字节对齐的第二个原因是因为微软倾向于命名它的填充(!)。如果在Reserved
之后有2个字节的未命名填充,则Microsoft会改为BYTE reserved[22]
。
是的,.Net字段偏移量也以字节为单位。
答案 1 :(得分:1)
声明如下:
[StructLayout(LayoutKind.Sequential)]
public struct NUMA_NODE_RELATIONSHIP
{
public uint NodeNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] Reserved;
public GROUP_AFFINITY GroupMask;
}
不需要明确的布局。让编组器使用与C ++编译器相同的规则布局结构更有意义。特别是当GROUP_AFFINITY
具有4或8个字节的对齐时,具体取决于机器指针的大小。显然,上述内容依赖于您GROUP_AFFINITY
正确。