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的。这是什么回事呢?我没找到相关的文档。

  • 相关阅读:
    topshelf和quartz
    Dapper的使用
    多快好省的做个app开发
    端口扫描之王——nmap入门精讲(转)
    你对自己的定位是什么,就能成为什么样的人(转)
    2015工作总结及2016展望
    使用php+swoole对client数据实时更新(二) (转)
    解决一bug的流程复盘
    JSONObject与JSONArray的使用
    GDB十分钟教程
  • 原文地址:https://www.cnblogs.com/rader/p/2181203.html
Copyright © 2011-2022 走看看