2009-07-27 60 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