Marshal.SizeOf返回错误大小问题排查求助
解决Marshal.SizeOf返回错误大小的问题
嘿,我之前也踩过Marshal.SizeOf的坑,咱们来一步步拆解你遇到的问题:
最可能的几个原因及解决办法:
1. 混淆了值类型(struct)和引用类型(class)的计算逻辑
如果你的"结构体"实际上是用class定义的,那Marshal.SizeOf返回的只是对象引用的大小(32位系统4字节,64位系统8字节),再加上CLR内部的额外字节,这就会出现你看到的14/16字节的结果。
解决办法:确保你的类型是struct而非class,同时指定布局属性:
// 正确写法:用struct + 指定布局规则 [StructLayout(LayoutKind.Sequential)] public struct YourStructName { // 字段定义 }
2. 数组是引用类型,Marshal仅计算指针大小
你提到的serializedPublicBytes如果是普通的byte[],在非托管内存中它只是一个指针(4/8字节),而非数组实际的91字节内容。Marshal.SizeOf只会计算非托管布局下的结构体本身大小,不会自动递归计算引用类型的内容。
解决办法:如果数组是固定长度,用[MarshalAs]标记为固定大小数组,让Marshal把数组字节数纳入计算:
[StructLayout(LayoutKind.Sequential, Pack = 1)] // Pack=1避免内存对齐带来的额外字节 public struct YourStructName { // 标记为固定长度91的数组 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 91)] public byte[] serializedPublicBytes; // 你的其他6字节字段示例 public byte Field1; public byte Field2; public int Field3; // 2+4=6字节,匹配你说的其余部分 }
3. 内存对齐导致的额外字节
默认情况下,CLR会对结构体字段进行内存对齐(比如int字段会对齐到4字节边界),这可能让实际大小比你手动计算的多几个字节。比如你的6字节字段可能因为对齐被填充到8字节,导致总大小偏差。
解决办法:在StructLayout中添加Pack = 1属性,强制取消对齐,让字段紧密排列:
[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct YourStructName { // 字段定义 }
测试验证
用上面的正确结构体定义,运行以下代码:
var instance = new YourStructName(); instance.serializedPublicBytes = new byte[91]; int calculatedSize = Marshal.SizeOf(instance); Console.WriteLine(calculatedSize); // 应该输出91+6=97,和你的预期一致
内容的提问来源于stack exchange,提问作者Snipe3000
相关产品推荐
相关产品推荐

