64位P /调用Idiosyncrasy
我想正确地为一个P/Invoke组织一些结构,但在64位操作系统上测试时发现奇怪的行为。64位P /调用Idiosyncrasy
我有一个结构定义为:
/// <summary>http://msdn.microsoft.com/en-us/library/aa366870(v=VS.85).aspx</summary>
[StructLayout(LayoutKind.Sequential)]
private struct MIB_IPNETTABLE
{
[MarshalAs(UnmanagedType.U4)]
public UInt32 dwNumEntries;
public IntPtr table; //MIB_IPNETROW[]
}
现在,拿到表的地址,我愿做一个Marshal.OffsetOf()调用像这样:
IntPtr offset = Marshal.OffsetOf(typeof(MIB_IPNETTABLE), "table");
这应该是4 - 我已经倾倒了缓冲区的字节来确认这一点,并且用我的指针算术中的硬编码4代替了上述调用,从而产生了正确的结果。
我得到预期的4,如果我实例MIB_IPNETTABLE并执行以下电话:结构中的一个字段的偏移量应该是前场的大小之和,正确
IntPtr offset = (IntPtr)Marshal.SizeOf(ipNetTable.dwNumEntries);
现在,在一个连续的?或者当它是一个非托管结构的情况下,偏移量真的是8(在x64系统上),但是仅在编组魔法之后变为4?有没有办法让OffsetOf()调用给我正确的偏移量?我可以使用调用SizeOf(),但OffsetOf()更简单的更大的结构。
在64位C/C++版本中,由于对齐要求(除非您强制要求),您的table
字段的偏移量将为8。我怀疑是CLR在做同样的给你:
对象的成员布局顺序,在它们出现时 出口到非托管内存的顺序。会员根据
StructLayoutAttribute.Pack
中规定的包装进行布置,并且可以不连续。
您可以wnat使用该属性或使用LayoutKind.Explicit
属性与FieldOffset
属性沿每个字段,如果你需要控制的那个级别。
谢谢您确认我对非托管路线的怀疑。 FieldOffset的显式布局是我正在寻找的。 – 2010-10-11 14:59:52
该结构翻译不正确。事实上,在一个内联数组中的“表”。 – 2014-01-13 22:30:19