代码之家  ›  专栏  ›  技术社区  ›  SwDevMan81 Chris Barlow

非对象字段错误对齐或重叠不正确

  •  9
  • SwDevMan81 Chris Barlow  · 技术社区  · 15 年前

    我正在尝试创建以下结构:

        [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;
        }
    

    我得到以下错误:

    无法从程序集加载类型“message”,因为它在偏移量4处包含一个对象字段,该字段未正确对齐或被非对象字段重叠。

    有人知道这是导致错误的原因吗?

    注意:我不能使用pack,因为我正在使用紧凑框架。 谢谢。

    2 回复  |  直到 15 年前
        1
  •  8
  •   ctacke    15 年前

    CF封送拆收器不太擅长这种类型的事情,您尝试的是不受支持的。问题是它知道第一个元素没有对齐,但似乎不理解数组中的每个元素也没有对齐。

    您可以在本例中看到行为的工作原理:

    [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;
    }
    
        2
  •  1
  •   Reed Copsey    15 年前

    出现问题的原因是数组与“x”重叠。ULUN,C,是UIT64(在C++中,ULUN是UIT32),所以实际上是8字节。

    如果将第二个fieldoffset更改为8,或将x更改为uint,则该值将消失。