我有以下结构
[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
。要解决此问题,请使用 StructLayoutAttribute
的 Pack
字段。
[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/