C# 非对象字段错误对齐或重叠

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1190079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 10:24:53  来源:igfitidea点击:

Incorrectly aligned or overlapped by a non-object field error

c#compact-frameworkalignmentstructureexplicit

提问by SwDevMan81

I'm trying to create the following structure:

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

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

and I get the following error:

我收到以下错误:

Could not load type 'Message' from assembly because it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field.

无法从程序集中加载类型“消息”,因为它包含偏移 4 处的对象字段,该字段未正确对齐或与非对象字段重叠。

Does anyone know why this is causing an error?

有谁知道为什么这会导致错误?

Note: I can not use Pack because I'm working with the compact framework. Thanks.

注意:我不能使用 Pack,因为我使用的是紧凑型框架。谢谢。

采纳答案by ctacke

The CF Marshaler isn't so good at this type of thing and what you're attempting is unsupported. The problem is that it knows that the first element is unaligned, but it seems to not understand that each element in the array would also be unaligned.

CF Marshaler 不太擅长这种类型的事情,并且您正在尝试的内容不受支持。问题是它知道第一个元素未对齐,但它似乎不明白数组中的每个元素也会未对齐。

You can see the behavior works in this example:

您可以看到此示例中的行为有效:

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

For this type of structure, I never let the marshaler try to handle each of the members anyway. The structure is small, so break out each individual item like this:

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

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

or use a simulated "union" like this:

或使用这样的模拟“联合”:

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

回答by Reed Copsey

The problem is occurring because your array is overlapping "X". ulong, in C#, is UInt64 (in C++, ulong is UInt32), so it's actually 8 bytes.

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

If you change your second FieldOffset to 8, or changed X to uint, this will go away.

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