C# StructLayout.Explicit 问题

标签 c# .net clr structlayout

我试图理解为什么下面的第二个例子没有问题,但第一个例子给了我下面的异常(exception)。在我看来,这两个例子都应该根据描述给出一个异常(exception)。谁能赐教一下?

Unhandled Exception: System.TypeLoadException: Could not load type 'StructTest.OuterType' from assembly 'StructTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
at StructTest.Program.Main(String[] args) Press any key to continue . . .

示例 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 个字节,因此如果您将整数放在距离结构开头不到四个字节的位置,您会有重叠的字段。有趣的是,您的两个代码片段在 64 位运行时都失败了,因为指针大小为 8 个字节。

关于C# StructLayout.Explicit 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1182782/

相关文章:

c# - 在 C# 中使用不带 TO 的密件抄送通过 SMTP 发送邮件

c# - 如何避免使用成员(member)提供者?

c# - 如何制作一个具有多个键和廉价的 Contains 操作的字典?

c# - 是否可以使 CLR JIT 在 WP7 中使用来自 C# 的 SIMD?

c# - 网络共享上的 .NET 4.0 应用程序导致 SecurityException

c# - 如何使 EF-Core 使用 Guid 而不是字符串作为其 ID/主键

C# 网络凭据未传递到服务器?

c# - ASP.Net 模拟方法的差异

c# - C#-为什么我的用于错误处理的包装函数无法捕获异常?

c++ - mouse_event MOUSEEVENTF_LEFTDOWN 注册为选项卡而不是左键单击?