c# - x64 上的 TypeLoadException 但在具有 structlayouts 的 x86 上没问题

标签 c# .net x86 64-bit

如果你想看到实际的异常,你需要一台 64 位机器。我创建了一些重现问题的虚拟类。

[StructLayout(LayoutKind.Sequential, Pack = 1)]
    public class InnerType
    {
        char make;
        char model;
        UInt16 series;
    }

 [StructLayout(LayoutKind.Explicit)]
    public class OutterType
    {
        [FieldOffset(0)]
        char blah;

        [FieldOffset(1)]
        char blah2;

        [FieldOffset(2)]
        UInt16 blah3;

        [FieldOffset(4)]
        InnerType details;
    }

    class Program
    {
        static void Main(string[] args)
        {
            var t = new OutterType();
            Console.ReadLine();
        }
    }

如果我在 64 位 clr 上运行它,我会收到类型加载异常,

System.TypeLoadException was unhandled 
  Message="Could not load type 'Sample.OutterType' from assembly 'Sample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field."

如果我强制 objective-c pu 为 32,它工作正常。

此外,如果我将 InnerType 从类更改为结构,它也可以工作。有人可以解释发生了什么事或我做错了什么吗?

谢谢

最佳答案

关于重叠类型的部分在这里具有误导性。问题是在 .Net 中,引用类型必须始终在指针大小边界上对齐。您的联合在 x86 中工作,因为字段偏移量是 4 个字节,这是 32 位系统的指针大小,但在 x64 上失败,因为它必须偏移 8 的倍数。如果将偏移量设置为 3 或5 在 x86 平台上。

编辑:对于怀疑者 - 我在互联网上找不到现成的引用,但请查看 Expert .NET 2.0 IL Assembler By Serge Lidin第 175 页。

关于c# - x64 上的 TypeLoadException 但在具有 structlayouts 的 x86 上没问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/456696/

相关文章:

c# - TSQL - 通过密码短语解密 : Noise in strings

c# - 如何根据 wpf 中的值使特定颜色变暗或变亮?

c# - 获取 Teams Calls 退回未在我们商店注册的应用程序

assembly - IA-32 组件 : Effect of 8 bit operations on 32 bit registers

c# - MySql.Data.MySqlClient.MySqlException - 已经有一个与此连接关联的打开的 DataReader,必须先将其关闭

c# - 在 C# .NET block 中等待 Task.WhenAll 吗?

c# - 对 Windows 窗体控件进行线程安全调用

c# - 如何使用 Newtonsoft Json.Net 反序列化接口(interface)

assembly - x86-64 和远程调用/跳转

assembly - 使用 .word 65535 会导致 QEMU 重新启动