【问题标题】:Incorrectly aligned or overlapped by a non-object field error非对象字段错误对齐或重叠
【发布时间】:2010-11-14 11:23:31
【问题描述】:

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

    [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,因为我正在使用紧凑的框架。 谢谢。

【问题讨论】:

    标签: c# compact-framework alignment structure explicit


    【解决方案1】:

    出现问题是因为您的数组与“X”重叠。 ulong 在 C# 中是 UInt64(在 C++ 中,ulong 是 UInt32),所以它实际上是 8 个字节。

    如果您将第二个 FieldOffset 更改为 8,或将 X 更改为 uint,这将消失。

    【讨论】:

    • @Reed - 谢谢,我现在将其更改为 ushort,但仍然出现错误,ushort 是 4 字节吗?我查看了 msdn 和 sizeof(ushort) 是 2,但我得到了错误。当我将 fieldoffset 更改为 4 时,它可以工作。
    • 我的猜测现在是对齐问​​题,我需要在 4 字节边界上启动数组吗?我在网上找不到任何东西
    • 数组在 CF 中必须是 DWORD 对齐的。有关更多详细信息和潜在的解决方法,请参阅我的答案。
    • @ctacke:是的 - 4 字节对齐是这里的问题......忘记了对 CF 的限制。
    【解决方案2】:

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

    对于这种类型的结构,我从不让 marshaler 尝试处理每个成员。结构很小,所以像这样分解每个单独的项目:

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

    【讨论】:

    • 好的,所以最简单的答案在您的评论中:数组必须在 CF 中以 DWORD 对齐
    • @ctacke:您能否向我推荐一个包含有关 CF Marshaler 详细信息的参考资料(例如,数组必须是 DWORD 格式)?
    • @david:我不知道。我对 marshaler 及其能力(或缺乏能力)的所有了解来自与 CF 团队的会面和对话,以及多年试图让它做我想做的事情的经验。
    猜你喜欢
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多