如何在 C# 中使用 Marshal.SizeOf() 正确计算结构大小?
How to correctly calculate struct size using Marshal.SizeOf() in C#?
我正在用这个来敲我的头。
我有一个 C# 结构:
[StructLayout(LayoutKind.Sequential)]
public struct Enroll
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 101)]
public char[] Name;
public UInt16 Port;
public byte Num;
public byte Max;
public UInt64 Version;
public byte TS;
public byte Avg;
public byte Flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public char[] Tag;
}
总共有 132 个字节。
不过
S.Enroll X = new();
int size = Marshal.SizeOf(X);
计算出 144 个字节,从而阻止我成功地将字节映射到结构。
Sender 是一个 C++ 应用程序,其结构声明如下:
struct Enroll
{
public:
char Name[101] = { 0 };
uint16 Port = 0;
uint8 Num = 0;
uint8 Max = 0;
uint64 Version = 0;
uint8 TS = 0;
uint8 Avg = 0;
DevFlags Flags = DevFlags ::None;
char Tag[16] = { 0 };
};
这导致实际的 132 个字节,我可以一个一个读取。
我错过了什么?
谢谢
正如 Matthew Watson 所建议的,Pack=1 解决了我的问题。 Link 由 Sinatr 解释:
The Pack field controls the alignment of a type's fields in memory. It
affects LayoutKind.Sequential. By default, the value is 0, indicating
the default packing size for the current platform. The value of Pack
must be 0, 1, 2, 4, 8, 16, 32, 64, or 128:
The fields of a type instance are aligned by using the following
rules:
The alignment of the type is the size of its largest element (1, 2, 4,
8, etc., bytes) or the specified packing size, whichever is smaller.
Each field must align with fields of its own size (1, 2, 4, 8, etc.,
bytes) or the alignment of the type, whichever is smaller. Because the
default alignment of the type is the size of its largest element,
which is greater than or equal to all other field lengths, this
usually means that fields are aligned by their size. For example, even
if the largest field in a type is a 64-bit (8-byte) integer or the
Pack field is set to 8, Byte fields align on 1-byte boundaries, Int16
fields align on 2-byte boundaries, and Int32 fields align on 4-byte
boundaries.
Padding is added between fields to satisfy the alignment requirements.
我正在用这个来敲我的头。 我有一个 C# 结构:
[StructLayout(LayoutKind.Sequential)]
public struct Enroll
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 101)]
public char[] Name;
public UInt16 Port;
public byte Num;
public byte Max;
public UInt64 Version;
public byte TS;
public byte Avg;
public byte Flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public char[] Tag;
}
总共有 132 个字节。 不过
S.Enroll X = new();
int size = Marshal.SizeOf(X);
计算出 144 个字节,从而阻止我成功地将字节映射到结构。
Sender 是一个 C++ 应用程序,其结构声明如下:
struct Enroll
{
public:
char Name[101] = { 0 };
uint16 Port = 0;
uint8 Num = 0;
uint8 Max = 0;
uint64 Version = 0;
uint8 TS = 0;
uint8 Avg = 0;
DevFlags Flags = DevFlags ::None;
char Tag[16] = { 0 };
};
这导致实际的 132 个字节,我可以一个一个读取。
我错过了什么?
谢谢
正如 Matthew Watson 所建议的,Pack=1 解决了我的问题。 Link 由 Sinatr 解释:
The Pack field controls the alignment of a type's fields in memory. It affects LayoutKind.Sequential. By default, the value is 0, indicating the default packing size for the current platform. The value of Pack must be 0, 1, 2, 4, 8, 16, 32, 64, or 128:
The fields of a type instance are aligned by using the following rules:
The alignment of the type is the size of its largest element (1, 2, 4, 8, etc., bytes) or the specified packing size, whichever is smaller.
Each field must align with fields of its own size (1, 2, 4, 8, etc., bytes) or the alignment of the type, whichever is smaller. Because the default alignment of the type is the size of its largest element, which is greater than or equal to all other field lengths, this usually means that fields are aligned by their size. For example, even if the largest field in a type is a 64-bit (8-byte) integer or the Pack field is set to 8, Byte fields align on 1-byte boundaries, Int16 fields align on 2-byte boundaries, and Int32 fields align on 4-byte boundaries.
Padding is added between fields to satisfy the alignment requirements.