c# - Marshal.SizeOf 结构返回过多的数字

标签 c# struct sizeof

我有以下结构

[StructLayout(LayoutKind.Sequential)]
public struct SFHeader
{

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
    public string FileName;

    public int Offset;

    public short Size;

    public byte Flags;

    public byte Source;


    public long LastWriteTime;


    public byte[] GetBytes()
    {
        int size = Marshal.SizeOf(this);
        var buffer = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.StructureToPtr(this, ptr, true);
        Marshal.Copy(ptr, buffer, 0, size);
        Marshal.FreeHGlobal(ptr);

        return buffer;
    }


    public static SFHeader FromBytes(byte[] buffer)
    {
        var str = new SFHeader();
        int size = Marshal.SizeOf(str);

        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.Copy(buffer, 0, ptr, size);
        str = (SFHeader)Marshal.PtrToStructure(ptr, str.GetType());
        Marshal.FreeHGlobal(ptr);

        return str;
    }

}

我需要将我的结构转换为一个字节数组(以通过套接字作为数据包发送),所以我使用了 GetBytes 方法,但它返回了一个 24 字节而不是 21 字节的数组:

  • 文件名(字符串):5字节
  • 偏移量(整数):4字节
  • 大小(短):2 个字节
  • 标志(字节):1 字节
  • 来源(字节):1字节
  • LastWriteTime(长):8 字节

所以:5+4+2+1+1+8 = 21 字节。
发生这种情况是因为 Marshal.SizeOf 返回 24,为什么? 而且看起来多余的字节放在字符串的字节之后,实际上例如以下结构:

var header = new SFHeader()
{
   FileName = "aaaa",
   Offset = 1,
   Size = 1
};

转换为以下缓冲区:

[0] = 97
[1] = 97
[2] = 97
[3] = 97
[4] = 0
[5] = 0
[6] = 0
[7] = 0
[8] = 1
[9] = 0
[10] = 0
[11] = 0
[12] = 1
[13] = 0
... The following are all zero (0)

第五、六、七是多余的字节。 我该如何解决这个问题?

最佳答案

您遇到了字节对齐问题。为了使字段保持在字边界上以提高访问速度,编译器用 3 个额外字节填充您的 string。要解决此问题,请使用 StructLayoutAttributePack 字段。

[StructLayout(LayoutKind.Sequential, Pack=1)]  // notice the packing here
public struct SFHeader
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
    public string FileName;

    public int Offset;

    public short Size;

    public byte Flags;

    public byte Source;

    public long LastWriteTime;
}

关于c# - Marshal.SizeOf 结构返回过多的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13233812/

相关文章:

c# - 反序列化客户端 AJAX JSON 日期

c - 在 C 中,结构成员可以使用与类型相同的名称吗?

c# - 编码结构数组指针的最佳方法

c - C 中的 Strlen() 功能存在问题

c++ - 计算数组的非空元素

c# - 可以确定方法是由派生类调用还是直接作为自身调用? C#

c# - WPF Datagrid 焦点并突出显示最后一行

c - 具有两个空指针的结构的大小是 4?

c - C 中小于 8 位的位字段并集的打包结构的大小

c# - 您可以在非 Windows 平台上编写 C# 应用程序吗?