2010-10-11 72 views
2

我想正確地爲一個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()更簡單的更大的結構。

+0

該結構翻譯不正確。事實上,在一個內聯數組中的「表」。 – 2014-01-13 22:30:19

回答

2

在64位C/C++版本中,由於對齊要求(除非您強制要求),您的table字段的偏移量將爲8。我懷疑是CLR在做同樣的給你:

對象的成員佈局順序,在它們出現時 出口到非託管內存的順序。會員根據StructLayoutAttribute.Pack中規定的包裝進行佈置,並且可以不連續。

您可以wnat使用該屬性或使用LayoutKind.Explicit屬性與FieldOffset屬性沿每個字段,如果你需要控制的那個級別。

+0

謝謝您確認我對非託管路線的懷疑。 FieldOffset的顯式佈局是我正在尋找的。 – 2010-10-11 14:59:52