2009-07-27 58 views
8

我試圖創建下面的結構重疊:正確對齊或由非對象字段錯誤

[StructLayout(LayoutKind.Explicit, Size=14)] 
    public struct Message 
    { 
     [FieldOffset(0)] 
     public ushort X; 
     [FieldOffset(2)] 
     [MarshalAs(UnmanagedType.ByValArray, SizeConst=5)] 
     private ushort[] Y; 
     [FieldOffset(12)] 
     public ushort Z; 
    } 

,我得到以下錯誤:

未能加載類型「消息」從因爲它包含一個偏移量爲4的對象字段,該對象字段與非對象字段錯誤地對齊或重疊。

有誰知道爲什麼這會導致錯誤?

注:我無法使用Pack,因爲我正在使用緊湊框架。 謝謝。

回答

8

CF Marshaler不太擅長這種類型的東西,而您嘗試的東西不受支持。問題是它知道第一個元素是未對齊的,但它似乎不明白,數組中的每個元素也是未對齊的。

您可以看到的行爲在這個例子中的工作原理:

[StructLayout(LayoutKind.Explicit, Size = 14)] 
public struct Message 
{ 
    [FieldOffset(0)] 
    public ushort X; 

    [FieldOffset(2)] 
    private ushort Y1; 

    [MarshalAs(UnmanagedType.LPArray)] 
    [FieldOffset(4)] 
    private ushort[] Y2; 

    [FieldOffset(12)] 
    public ushort Z; 
} 

對於這種類型的結構,我從來沒有讓封送仍會嘗試處理每個成員。結構小,所以打出來的每個單獨的項目是這樣的:

[StructLayout(LayoutKind.Explicit, Size = 14)] 
public struct Message 
{ 
    [FieldOffset(0)] 
    public ushort X; 

    [FieldOffset(2)] 
    private ushort Y1; 

    [FieldOffset(4)] 
    private ushort Y2; 

    [FieldOffset(6)] 
    private ushort Y3; 

    [FieldOffset(8)] 
    private ushort Y4; 

    [FieldOffset(10)] 
    private ushort Y5; 

    [FieldOffset(12)] 
    public ushort Z; 
} 

或使用模擬的「聯盟」是這樣的:

public struct Y 
{ 
    public ushort a; 
    public ushort b; 
    public ushort c; 
    public ushort d; 
    public ushort e; 
} 

[StructLayout(LayoutKind.Explicit, Size = 14)] 
public struct Message 
{ 
    [FieldOffset(0)] 
    public ushort X; 

    [FieldOffset(2)] 
    private Y Y; 

    [FieldOffset(12)] 
    public ushort Z; 
} 
1

問題發生是因爲你的數組重疊「X」。在C#中,ulong是UInt64(在C++中,ulong是UInt32),所以它實際上是8個字節。

如果您將第二個FieldOffset更改爲8,或將X更改爲uint,則此操作將消失。

+0

@Reed - 謝謝,我現在改成了一個USHORT和我仍然得到錯誤,是4字節的ush?我看過msdn和sizeof(ushort)是2,但我得到錯誤。當我將fieldoffset更改爲4時,它可以正常工作。 – SwDevMan81 2009-07-27 19:33:37

+0

我的猜測現在是它的一個對齊問題,我需要在4字節邊界上啓動數組嗎?我無法在網上找到任何東西 – SwDevMan81 2009-07-27 19:36:56