c# - 包含 guid 的结构上的 Marshal.SizeOf 提供额外的字节

标签 c# struct size marshalling guid

我有几个具有顺序布局的结构:

struct S1
{
  Guid id;
}

struct S2 
{
  Guid id;
  short s;
}

struct S3 
{
  Guid id;
  short s;
  short t;
}

在上述结构类型上调用 Marshal.SizeOf, 我得到了:

Size:
S1 = 16, as expected.
S2 = 20, copied an instance to a byte array, it only occupies first 18 bytes.
S3 = 20.

我的问题是,为什么 S2 的大小是 20 而不是 18。只有当 Guid 在结构中时才会出现这个问题。

很抱歉无法从 msdn 中找到任何有用的信息。我知道 Marshal.SizeOf 给出了该类型在内存中占用的空间大小,但我想知道为什么它需要 2 个额外字节才能使大小成为 4 的倍数。

我怎样才能避免这个“问题”?

非常感谢!

最佳答案

这是因为隐含的 [StructLayout] 附加到结构,Pack 字段是重要的字段。它规定了结构成员在编码后如何对齐。 Pack 的默认值为 8。这表示任何小于或等于 8 字节的成员都是对齐的。换句话说,short 将对齐到 2 的倍数的偏移量,int 对齐到 4,long 或 double 对齐到 8。

关键点是在创建结构数组时对齐仍然有效。用一个更简单的例子更容易演示:

using System;
using System.Runtime.InteropServices;

class Program {
    static void Main(string[] args) {
        Console.WriteLine(Marshal.SizeOf(typeof(Example)));
        Console.ReadLine();
    }
}
struct Example {
    public int a;
    public short b;
}

输出:8

a 成员强制增加大小,将两个额外的填充字节添加到结构中,以确保在使用结构时 int 仍然与 4 的倍数的偏移量对齐数组。您可以通过应用属性来更改结果:

[StructLayout(LayoutKind.Sequential, Pack = 2)]
struct Example {
    public int a;
    public short b;
}

输出:6

当在数组中使用该结构时,a 成员现在将错位。

回到Guid,从声明中看不出来,但它内部是由一些成员组成的。第一个是名为 _a 的私有(private)字段,它是一个 int。因此,Guid 需要 4 字节对齐。因此,需要 2 个额外的填充字节才能使您的结构在数组中使用时正确对齐。您需要在 S2 上使用 Pack=1 或 Pack=2 才能获得 18 个字节。

this answer 中了解有关结构的更多背景知识以及它们在 .NET 中的特殊处理方式.

关于c# - 包含 guid 的结构上的 Marshal.SizeOf 提供额外的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12572666/

相关文章:

c++ - C/C++ : passing a struct/class with a member array to a function by value

c - 查找数组的大小和单词洗牌

javascript - CSS 字体大小呈现得太小,中间大小百分比不起作用

html - 下拉菜单框大小不一样

c# - 在我的游戏中使用什么代替 Application.DoEvents?

c# - 数据网格未正确更新,滚动时更新

c++ - c++中的atof、结构和指针

c++ - 为什么结构体的 sizeof 不等于每个成员的 sizeof 之和?

c# - 在完成订购任务后获取对原始任务的引用?

C# 禁用事件处理程序问题