我试图理解为什么下面的第二个例子没有问题,但第一个例子给了我下面的异常(exception)。在我看来,这两个例子都应该根据描述给出一个异常(exception)。任何人都可以启发我吗?
示例 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace StructTest
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct InnerType
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
char[] buffer;
}
[StructLayout(LayoutKind.Explicit)]
struct OuterType
{
[FieldOffset(0)]
int someValue;
[FieldOffset(0)]
InnerType someOtherValue;
}
class Program
{
static void Main(string[] args)
{
OuterType t = new OuterType();
System.Console.WriteLine(t);
}
}
}
示例 2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace StructTest
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct InnerType
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
char[] buffer;
}
[StructLayout(LayoutKind.Explicit)]
struct OuterType
{
[FieldOffset(4)]
private int someValue;
[FieldOffset(0)]
InnerType someOtherValue;
}
class Program
{
static void Main(string[] args)
{
OuterType t = new OuterType();
System.Console.WriteLine(t);
}
}
}
最佳答案
公共(public)语言运行时包含一个验证器,可确保运行的代码(可验证的 IL)不可能破坏托管环境中的内存。这可以防止您声明这样一个字段重叠的结构。基本上,您的结构包含两个数据成员。一个整数(4 个字节)和一个 native 整数(指针大小)。在 32 位 CLR(您可能正在其中运行代码)上,char[]
将占用 4 个字节,因此如果您将整数放在距结构开头少于 4 个字节的位置,则会出现重叠字段。有趣的是,您的两个代码片段在 64 位运行时都失败了,因为指针大小为 8 字节。
关于C# StructLayout.Explicit 问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1182782/