Marshal.Sizeof返回意外值

问题描述

我正在调试由第三方编写的C#代码。该项目是一个旧的C ++项目,已由承包商用C#重写,我无权访问承包商。我编写了原始的C ++版本。

问题是C#代码获取表示通过UDP连接接收的数据的结构的大小时。

该结构定义为:

[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;
}

此结构的大小检索为:

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

,返回的值是17,而不是预期的13。我怀疑 ip 成员有4个字节的差异,但这仅仅是因为它与其他成员的表达方式不同(带有'new' ),但我没有其他决定依据。

我通常不会在解析接收到的数据包的问题的C#代码中使用这种封送处理,因此我不知道如何修改此结构定义以使其与原始版本大小“对齐”,明智的。

我可以用元帅代替

int size = 13;

但这是作弊吧?

我可以以某种方式修改此布局以使尺寸正确显示吗?

解决方法

将此添加到结构中:

[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;
}

这将告诉编译器将其视为典型的C样式数组,而不是指针。该应该为字节,因为IP地址是一个无符号的char数组。这些类型的标题通常不使用char,通常使用byte(即unsigned char