运行时如何使用元数据

    为了更好的理解元数据及其它在CLR中所扮演的角色,自己动手编写代码并且演示元数据是怎么影响CLR是最好的方法。接下来有一个例子,在MyApp中定义了2个方法,Main函数是程序的入口点,Add方法接收两个int数,返回这两个整形数的和。
  1. using System;  
  2. public class MyApp
  3. {
  4.    public static int Main()
  5.    {
  6.       int ValueOne = 10;
  7.       int ValueTwo = 20;         
  8.       Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo));
  9.       return 0;
  10.    }
  11.    public static int Add(int One, int Two)
  12.    {
  13.       return (One + Two);
  14.    }
  15. }
    编译之后生成受控模块。执行该程序时,运行时加载受控模块(关于在.net中运行时如何加载受控模块参考之前的博客 http://blog.csdn.net/lastBeachhead/archive/2008/10/27/3161564.aspx)到内存中,并且向元数据咨询该类的详细信息。当必要时,运行时使用即时编译器把IL语言转换成本地可执行的机器语言。
接下来的是上面Main函数的IL代码。你可以使用ILDasm.exe去查看任何.NET应用程序的MSIL语言和元数据,不过个人推荐使用Reflector.exe。
  1.       .entrypoint
  2.       .maxstack  3
  3.       .locals ([0] int32 ValueOne,
  4.                [1] int32 ValueTwo,
  5.                [2] int32 V_2,
  6.                [3] int32 V_3)
  7.       IL_0000:  ldc.i4.s   10
  8.       IL_0002:  stloc.0
  9.       IL_0003:  ldc.i4.s   20
  10.       IL_0005:  stloc.1
  11.       IL_0006:  ldstr      "The Value is: {0}"
  12.       IL_000b:  ldloc.0
  13.       IL_000c:  ldloc.1
  14.       IL_000d:  call int32 ConsoleApplication.MyApp::Add(int32,int32) /* 06000003 */

    即时编译器从整个方法中读取MSIL代码,分析代码,然后生成相应的本地指令。在IL_000D,即时编译器发现了一个Add方法的标记,即时编译器使用Add这个标记去向元数据中方法定义表MethodDef中找寻,结果在该表的第三行找到了。
    接下来的表格显式了MethodDef表的一部分。受控代码生成的受控模块中还有其它各种各样的表,此处只讨论MethodDef表。

    该表的每一列都包含重要的信息。运行时通过RVA列的值去计算出绝对位置。ImpIFlags和Flags两个列包含一些位标记来描述方法。Name列允许运行时根据该列中的名字去从string heap中索引。Signature列允许运行时从blob heap中索引方法签名。
    使用元数据,运行时能够访问到所有它需要的信息(去何处装载你的代码以及如何去处理等)。在这种意义上,元数据是一种自描述文件。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页