Marshal.Sizeof() returning unexpected value

327 Views Asked by At

I'm debugging code in C# written by a 3rd party. The project is an old C++ project that was rewritten in C# by a contractor, and I have no access to the contractor. I authored the original C++ version.

The issue is when the C# code gets the size of a structure that represents data received over a UDP connection.

The struct is defined as:

[StructLayout(LayoutKind.Sequential,Pack=1)]
internal class PROXY_HDR {
    public ushort pad;
    public ushort label;
    public char flags;
    public ushort length;
    public char[] ip = new char[4];
    public ushort port;
}

The size of this struct is retrieved as:

int size = Marshal.Sizeof(typeof(PROXY_HDR));

and the value returned is 17 instead of the expected 13. With a 4-byte difference, I suspect the ip member, but only because it's expressed differently than the other members (with 'new'), but I have no other basis to decide.

I don't typically use this type of marshaling in my C# code that parses received packets without a problem, so I don't know how to modify this struct definition to make it 'line up' with the original version size-wise.

I could replace the Marshal line with

int size = 13;

but that's cheating, right?

Can I modify this layout somehow to get the size to come out right?

1

There are 1 best solutions below

5
Andy On BEST ANSWER

Add this to the structure:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal class PROXY_HDR
{
    public ushort pad;
    public ushort label;
    public byte flags;
    public ushort length;
    [MarshalAs(UnmanagedType.ByValArray,
        SizeConst = 4, ArraySubType = UnmanagedType.U1)]
    public byte[] ip;
    public ushort port;
}

This will tell the compiler to treat it as a typical C-style array, not a pointer. This should be byte, as an IP address is an unsigned char array. char typically isn't used in these types of headers, it's usually byte (i.e: unsigned char)