• TypeLoadException Could not load type because the format is invalid


    异常发生的背景

    这是一段运行时的错误,完整的错误信息如下:

    Test method ***.Tests.IpHelperTest.TestMarshalSize threw exception:
    System.TypeLoadException: Could not load type '***.Network.Protocol.ConnectionRequest' from assembly '***, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because the format is invalid.

    引发错误的代码是一段单元测试的代码:

            [TestMethod]
    publicvoid TestMarshalSize()
    {
    var size
    = Marshal.SizeOf(typeof(ConnectionRequest));
    Assert.AreEqual(
    7, size);
    }

    其中ConnectionRequest是这样定义的:

        [StructLayout(LayoutKind.Sequential, Pack =1, CharSet = CharSet.Ansi)]
    publicclass ConnectionRequest:MessageBase
    {
    publicbyte ClassID;
    public ProtocolVersion ProtocolVersion;
    }

    异常分析和解决

    非常简单的代码,但是报的错误却让人摸不着头脑。起先我以为是dll编译的设置不对,比如测试项目编译为x64,但是被测试的代码库编译成32位的。检查之后,我的项目不存在这个问题。实际上,问题存在于ConnectionRequest父类的定义中。先来看一下MessageBase的定义:

    publicabstractclass MessageBase
    {
    public DataPacketHeader header;
    }

    我没有为MessageRequest定义StructLayout,因为我并不打算对MessageBase进行Marshal的操作。然而,这似乎不符合C#对Marshal操作的要求,如果要对一个类做Marshal的操作,那么我们必须为它的父类也设置StructLayout即使它的父类里什么都没有。所以要解决TypeLoadException的问题,我们需要对MessageBase设置StructLayout。

    发现新问题

    但是,我又发现一个问题: 如果我们自定义的一个类不显示地继承其它的类,那它实际上会继承Object类。如果自定义的类要做Marshal,那么Object类也要定义StructLayout了,但是检查Object的定义发现是没有StructLayout的。这是什么回事呢?我没找到相关的文档。

  • 相关阅读:
    配置wpa_supplicant调试wifi linux下命令行连接wifi
    Android平台开发-WIFI 驱动移植 -- 详细
    明远智睿IMX6Q Android4.4.2移植USBWIFI(RTL8188EUS)
    android上USB Wifi调试记录
    Android wifi驱动的移植 realtek 8188
    CCF-CSP-201703-4-地铁修建
    CCF-CSP-201709-4-通信网络
    CCF-CSP-201409-4-最优配餐
    CCF/CSP-201612-4-压缩编码
    CCF/CSP-201612-3-权限查询
  • 原文地址:https://www.cnblogs.com/rader/p/2181203.html
Copyright © 2020-2023  润新知