如果你只做能力范围之内的事,你就永远不会有进步!|

陈侠云

园龄:2年10个月粉丝:1关注:1

《NET CLR via C#》---第三章("运行时"解析类型引用)

"运行时"解析类型引用

  1. 首先在"C:\Users\LH89\source\repos"目录下,新建Console1工程(C#控制台)
    image
  2. 实现简单的代码,并编译为程序集(假定名为Program.exe)
using System;

public class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World");
    }
}
  1. 运行应用程序,CLR会加载并初始化自身,读取程序集的CLR头,查找标识了应用程序入口方法(Main)的MethodDefToken,检索MethodDef元数据表找到方法的IL代码在文件中的偏移量,将IL代码JIT编译成本机代码,最后执行本地代码。
  2. 通过对程序集运行ILDasm.exe并选择“视图/显示字节”,双击树形视图中的Main方法。
    image
  3. 对这些代码进行JIT编译,CLR会检测所有类型和成员引用,加载它们的定义程序集(如果尚未加载)。
  4. 上述代码包含对System.Console.WriteLine的引用。具体来说,IL call指令引用了元数据token 0A000011。该token标识MemberRef元数据表(表0A)中的记录项。CLR检查该MemberRef记录项,发现它的字段引用了TypeRef表中的记录项(System.Console类型)。按照TypeRef记录项,CLR被引导至一个AssemblyRef记录项:“mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”,这时CLR就知道了它需要的是哪个程序集。接着,CLR必须定位并加载该程序集。
    image
    image
  5. 解析引用的类型时,CLR可能在以下三个地方找到类型。
  • 相同文件
    编译时便能发现对相同文件中的类型的访问,这称为早期绑定。类型直接从文件中加载,执行继续。
  • 不同文件,相同程序集
    “运行时”确保被引用的文件在当前程序集元数据的FileDef表中,检查加载程序集清单文件的目录,加载被引用的文件,检查哈希值以确保文件完整性。发现类型的成员,执行继续
  • 不同文件,不同程序集
    如果引用的类型在其他程序集的文件中,“运行时”会加载被引用程序集的清单文件。如果需要的类型不在该文件中,就继续加载包含了类型的文件。发现类型的成员,执行继续。
  1. 在上例中,CLR发现System.Console在和调用者不同的程序集中实现。所以,CLR必须查找哪个程序集,加载包含程序集清单的PE文件。然后扫描清单,判断是哪个PE文件实现了类型。如果被引用的类型就在清单文件中,一切都很简单。如果类型在程序集的另一个文件中,CLR必须加载那个文件,并扫描其元数据来定位类型。然后CLR创建它的内部数据结构来表示类型,JIT编译器完成Main方法的编译。
    image

本文作者:陈侠云

本文链接:https://www.cnblogs.com/chenxiayun/p/18330374

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   陈侠云  阅读(29)  评论(0编辑  收藏  举报
//雪花飘落效果
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起