문제

I am having "Incorrectly aligned or overlapped by non-object field" error with the following code.

public struct TypeA
{
   public string A1;
   public string A2;
}
public struct TypeB
{
   public string B1,
   public string B2;
}

I implemented union by using System.Runtime.InteropServices with LayoutKind.Explicit

[StructLayout(LayoutKind.Explicit)]
public struct TypeAorB
{
   [FieldOffset(0)]
   public TypeA aa;

   [FieldOffset(0)]
   public TypeB bb;
}

I think the issue comes from string in the struct. How do I overcome this problem?

도움이 되었습니까?

해결책

What you are trying to do is not legal. String is a reference type and can't be overlapped with anything else in a union. It matters a great deal to the garbage collector, it can't reliable figure out what reference is stored in a field so it cannot reliable figure out if the string object needs to be kept alive.

What's bizarro about your structs is that you overlap a string with a string. Which would technically work, no reason for the garbage collector to be confused since it always sees a valid object reference. But it doesn't actually handle that special case, Microsoft didn't write enough code, or cared to burn the cpu cycles, to check for the type identity.

And that's for a good reason because you don't have to overlap them in your declaration. No point for Microsoft to write the special code to recognize the overlap when you can trivially avoid it.

And is turtles all the way down in your example, every field of union is identical. So there isn't any point at all in using a union.

So don't.

다른 팁

Why are the fieldoffsets the same? They should be 0 and 0+[size of TypeA].

Type A is 8 bytes as you have 2x strings, and each one will use a 4 byte pointer.

Therefore...

    [StructLayout(LayoutKind.Explicit)]
    public struct TypeAorB
    {
        [FieldOffset(0)]
        public TypeA aa;

        [FieldOffset(8)]
        public TypeB bb;
    }

If you were to add a third field of typeB again, you'd need to do:

    [StructLayout(LayoutKind.Explicit)]
    public struct TypeAorB
    {
        [FieldOffset(0)]
        public TypeA aa;

        [FieldOffset(8)]
        public TypeB bb;

        [FieldOffset(16)]
        public TypeB bb;
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top