6

I am using the following definition for my struct:

[StructLayout(LayoutKind.Explicit)]
public struct NetworkMessage
{

    [FieldOffset(0)]
    public MessageType Type;
    [FieldOffset(4)]
    public bool GatewayMessage;               

    //AuthenticationRequest
    [FieldOffset(5)]
    public char[] AuthenticationUsername; //20 charachters long
    [FieldOffset(13)]
    public byte[] AuthenticationPasswordHash; // 16 bytes long

    //Authntication result
    [FieldOffset(5)]
    public bool AuthenticationSuccess;
    [FieldOffset(6)]
    public char[] AuthenticationMessage;
}

However, when I attempt to use this type, I get this error message:

System.TypeLoadException: Could not load type 'NetworkMessage' from assembly because it contains an object field at offset 5 that is incorrectly aligned or overlapped by a non-object field.

Does non-object field mean how one is a value, and one is a reference? Can I not mix these?

Any help is much appreciated.

Thanks, Venatu

EDIT: Apologies, I should have been more explicit in that I am intending this as a kind of pseudo-union. The overlap is fields is intentional to allow me to use one struct as a multiple types of messages, making buffering and passing around the system easier. Sorry for any confusion

Venatu
  • 1,264
  • 1
  • 13
  • 24

1 Answers1

12

Arrays must start on 4-byte boundaries.

See this article for more information on using arrays in explicit structs. It also mentions the even boundary issue for arrays, and describes some alternative options for arrays in explicit structs.

http://www.developerfusion.com/article/84519/mastering-structs-in-c/

see also Incorrectly aligned or overlapped by a non-object field error

Community
  • 1
  • 1
  • I just tried moving AuthenticationUsername to an even boundary ie. 6 and removing the entire AuthenticationResult section (for simplicty while testing this). However, this failed. Yet when I moved it up to 8, and AuthenticationPasswordHash to 16, the exception disappeared. Does this mean that rather than even boundaries, it must be on an 8 byte boundary? – Venatu Jul 31 '11 at 20:49
  • Nevermind, got it. It must fall on a dword boundary, which in c# is equivalent to uint. Uint is 8 bytes in size, explaining the above. Cheers for the help, and the links – Venatu Jul 31 '11 at 21:17