Struct Layout on WinCE gives unexpected results
[StructLayout( LayoutKind.Explicit, Pack = 1, Size = 20 )]
public struct StatusStruct
{
/// <summary>
/// validation field
/// </summary>
[FieldOffset( 0 )]
public Int32 _magic;
/// <summary>
/// Packet sequence number
/// </summary>
[FieldOffset( 4 )]
public Int32 _seq;
/// <summary>
/// Packet timestam开发者_StackOverflow社区p
/// </summary>
[FieldOffset( 8 )]
public Int64 _timestamp;
/// <summary>
/// Length of data section
/// </summary>
[FieldOffset( 16 )]
public Int32 _len;
}
I have a strange problem on Arm4/WinCE where Marshal.SizeOf() for this struct returns 24 bytes, but on an x86/Win32 system it returns 20 bytes. This seriously hampers my interoperability over the wire. Anybody know why?
I can't explain it, but I can certainly confirm it. It also doesn't have to do with CPU architecture. On either an ARM or an x86 that struct ends up being 24 bytes long in the Compact Framework but 20 in the full framework. If I create the equivalent in native code it's the expected 20.
Looking at it in the Memory View, I can see that the compiler is adding 4 bytes of zero padding at the end of the structure, but I have no idea why.
var test = new StatusStruct()
{
_magic = unchecked((int)0xaaaaaaaa),
_seq = unchecked((int)0xbbbbbbbb),
_timestamp = unchecked((long)0xcccccccccccccccc),
_len = unchecked((int)0xdddddddd)
};
http://blog.opennetcf.com/ctacke/binary/struct_size.png
I'd definitely call this a bug in the CF.
Came up with a workaround that solves the problem. I added an additional "Int32 _unused" to the end of the struct so that it aligns the whole struct to an 8-byte boundary. The size is still 24 on Arm4, and 24 on x86. This gives me the interop I need. It would appear to be an alignment issue on Arm architectures. I suspect it has something to do with the Int64 member, but I'm not positive.
精彩评论