Marshal.SizeOf结构返回过多 [英] Marshal.SizeOf structure returns excessive number

查看:192
本文介绍了Marshal.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 字节数组:

I need to convert my structure to an array of byte (to send as packet with socket), so I use the GetBytes method, but it returns an array of 24 bytes instead of an array of 21 bytes:


  • 文件名(字符串):5字节

  • 偏移(INT):4字节

  • 尺寸(短):2字节

  • 标志(字节):1个字节

  • 源(字节):1个字节

  • LastWriteTime(长):8个字节

  • Filename (string): 5 bytes
  • Offset (int): 4 bytes
  • Size (short): 2 bytes
  • Flags (byte): 1 byte
  • Source (byte): 1 byte
  • LastWriteTime (long): 8 bytes

所以:5 + 4 + 2 + 1 + 1 + 8 = 21字节结果
这是因为 Marshal.SizeOf 24返回,为什么呢?
和似乎在过量的字节被放置在串中的字节之后,实际上例如下列结构:

So: 5+4+2+1+1+8 = 21 bytes.
This happens because Marshal.SizeOf returns 24, why? And it seems that the the bytes in excess are placed after the bytes of the string, in fact for example the following structure:

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



被转换为下面的缓冲液:

is converted to the following buffer:

[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)

第五,第六和第七是多余的字节数。
我怎样才能解决这个问题?

The fifth, sixth and seventh are the bytes in excess. How can I solve this problem?

推荐答案

您正在运行到一个字节对齐的问题。在试图保持对字边界字段的访问速度,编译器填充您的字符串 3额外的字节。为了解决这个问题,可以使用 StructLayoutAttribute

You're running into a byte-alignment issue. In an attempt to keep fields on word boundaries for speed of access, the compiler is padding your string with 3 extra bytes. To fix this, use the Pack field of the StructLayoutAttribute.

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

这篇关于Marshal.SizeOf结构返回过多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆