C# [StructLayout(LayoutKind.Sequential)]
这是 C# 语言中的一个特性(Attribute),用于控制结构体(struct)或类在内存中的字段排列方式。主要在与非托管代码(如 C++ DLL)交互时使用,确保托管内存布局与 C/C++ 结构体内存布局一致。
1. 作用
[StructLayout(LayoutKind.Sequential)] 告诉 .NET 运行时:按照字段在代码中声明的顺序,一个接一个地排列到内存中,不进行自动重排或优化。
[StructLayout(LayoutKind.Sequential)] struct MyStruct { int id; float value; byte flag; } // 内存布局: id (4字节) -> value (4字节) -> flag (1字节),可能尾部有填充
2. LayoutKind 的三种选项
| 枚举值 | 行为 | 适用场景 |
|---|---|---|
| Sequential | 字段按声明顺序布局(默认结构体就是此选项,显式写出来更清晰)。 | 与 C/C++ 结构体交互(P/Invoke),或者需要对布局有可预测的顺序。 |
| Explicit | 需要配合 [FieldOffset] 手动指定每个字段的偏移量(类似 C++ 的 union 或精细控制内存重叠)。 |
模拟联合体(union),或对接硬件寄存器。 |
| Auto | 运行时自动优化字段顺序(可能为了对齐/性能重新排列),默认用于引用类型(class)。 | 纯托管代码,不需要与非托管交互。 |
3. 为什么需要 Sequential?
-
默认情况:C# 的
struct默认是Sequential,但class默认是Auto。为清晰和兼容性,尤其在 P/Invoke 时,最好显式指定Sequential。 -
与非托管 DLL 通信:C/C++ 结构体是顺序排列的(除非有对齐和填充)。C# 要想安全地传递结构体给 C 函数(如
ReadProcessMemory、自定义 DLL 函数),必须确保内存布局一致。
// C++ 端定义 struct Point { int x; int y; }; // C# 端对应 [StructLayout(LayoutKind.Sequential)] struct Point { public int x; public int y; }

浙公网安备 33010602011771号