zoukankan      html  css  js  c++  java
  • 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的。这是什么回事呢?我没找到相关的文档。

  • 相关阅读:
    sqli-labs 第四关
    sqli-labs 第三关
    sqli-labs 第二关
    sqli-labs 第一关
    Buuctf-misc-假如给我三天光明
    Buuctf-misc-另外一个世界
    Buuctf-misc-FLAG
    量化投资_合成数据
    量化投资_止盈止损在策略中的有效性(改编)
    量化投资_金融数据信息处理的新维度(A New Dimension to Deal Data Information of Finance)【论文/时海涛】
  • 原文地址:https://www.cnblogs.com/rader/p/2181203.html
Copyright © 2011-2022 走看看