When you declare a structure like
struct CM_Request_AcceptAccount : BasePacketProto { unsigned char ACCOUNT_LOGIN[16]; unsigned char ACCOUNT_PASSWORD[16]; };
in C ++, an array is "inline" and "fixed" in length or, in other words, contributes 16 bytes each to the "size" of the structure.
But in C #, you re-declare the same structure as:
[StructLayout(LayoutKind.Sequential)] class CM_Request_AcceptAccount : BasePacketProto { public byte[] ACCOUNT_LOGIN = new byte[16]; public byte[] ACCOUNT_PASSWORD = new byte[16]; }
Here you do not indicate that the first 16 bytes belong to the ACCOUNT_LOGIN array, and the next 16 bytes belong to ACCOUNT_PASSWORD .
Line byte [] ACCOUNT_LOGIN = new byte [16]
says nothing to the marshaller. This causes the CLR to allocate a 16-byte array on the heap when an instance of CM_Request_AcceptAccount is created in the code.
To properly structure the structure, change the C # declaration to:
[StructLayout(LayoutKind.Sequential)] class CM_Request_AcceptAccount : BasePacketProto { [MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] public byte[] ACCOUNT_LOGIN; [MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] public byte[] ACCOUNT_PASSWORD; }
Additional info: Since your char arrays are for storing a C style string, you can also use
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)] public string ACCOUNT_LOGIN;
It should be remembered that the marshaller expects a null terminating character in 16 characters that you specified in your C ++ code.