Marshal.Sizeof() 返回意外值

use*_*770 3 c# c++ marshalling structlayout

我正在调试由 3rd 方编写的 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;
}
Run Code Online (Sandbox Code Playgroud)

此结构的大小检索为:

int size = Marshal.Sizeof(typeof(PROXY_HDR));
Run Code Online (Sandbox Code Playgroud)

并且返回的值是 17 而不是预期的 13。有 4 个字节的差异,我怀疑是ip成员,但这只是因为它的表达方式与其他成员不同(使用“new”),但我没有其他依据可以决定.

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

我可以用

int size = 13;
Run Code Online (Sandbox Code Playgroud)

但那是作弊,对吧?

我可以以某种方式修改此布局以使大小正确吗?

And*_*ndy 5

将此添加到结构中:

[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;
}
Run Code Online (Sandbox Code Playgroud)

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