Поделиться через


Использование метаданных во время выполнения

Для лучшего понимания метаданных и их роли в среде CLR полезно написать простую программу и наглядно проиллюстрировать, как метаданные влияют на работу среды выполнения. В приведенном ниже примере показано два метода внутри класса MyApp. Метод Main является точкой входа программы, а метод Add — просто возвращает сумму двух целочисленных аргументов.

Public Class MyApp
   Public Shared Sub Main()
      Dim ValueOne As Integer = 10
      Dim ValueTwo As Integer = 20
      Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo))
   End Sub
   
   Public Shared Function Add(One As Integer, Two As Integer) As Integer
      Return (One + Two)
   End Function
End Class
using System;  
public class MyApp
{
   public static int Main()
   {
      int ValueOne = 10;
      int ValueTwo = 20;         
      Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo));
      return 0;
   }
   public static int Add(int One, int Two)
   {
      return (One + Two);
   }
}

При запуске кода среда выполнения загружает модуль в память и обращается к метаданным за сведениями об этом классе. После загрузки среда выполнения проводит подробный анализ потока кода MSIL для метода, чтобы преобразовать его в инструкции машинного кода (выполнение которых осуществляется максимально быстро). В среде выполнения для преобразования инструкций MSIL в исходный машинный код используется JIT-компилятор. Преобразование выполняется по одному методу за раз по мере необходимости.

В приведенном ниже примере показана часть кода MSIL, полученного для функции Main из предыдущего кода. Код MSIL и метаданные любого приложения .NET Framework можно просмотреть при помощи дизассемблера MSIL (Ildasm.exe).

      .entrypoint
      .maxstack  3
      .locals ([0] int32 ValueOne,
               [1] int32 ValueTwo,
               [2] int32 V_2,
               [3] int32 V_3)
      IL_0000:  ldc.i4.s   10
      IL_0002:  stloc.0
      IL_0003:  ldc.i4.s   20
      IL_0005:  stloc.1
      IL_0006:  ldstr      "The Value is: {0}"
      IL_000b:  ldloc.0
      IL_000c:  ldloc.1
      IL_000d:  call int32 ConsoleApplication.MyApp::Add(int32,int32) /* 06000003 */

JIT-компилятор считывает код MSIL для всего метода, проводит тщательный анализ и создает эффективный набор машинных инструкций для этого метода. В строке IL_000d появляется лексема метаданных для метода Add (/* 06000003 */) и среда выполнения использует эту лексему для обращения к третьей строке таблице MethodDef.

В приведенной ниже таблице показана часть таблицы MethodDef, на которую ссылается лексема метаданных, описывающая метод Add. В сборке существуют и другие таблицы метаданных со своими уникальными значениями, но в данный момент рассматривается только эта таблица.

Строка

Относительный виртуальный адрес (RVA)

Неявные флаги

Флаги

Имя

(Указывает на кучу строк.)

Сигнатура (указывает на кучу больших двоичных объектов)

1

0x00002050

IL

Управляемое

Открытый

ReuseSlot

SpecialName

RTSpecialName

.ctor

.ctor (конструктор)

 

2

0x00002058

IL

Управляемое

Открытый

Static

ReuseSlot

Main

Строка

3

0x0000208c

IL

Управляемое

Открытый

Статический

ReuseSlot

Add

int, int, int

В каждом столбце таблицы содержатся важные сведения о коде. Значения в столбце RVA позволяют среде выполнения вычислить начальный адрес в памяти кода MSIL, определяющего этот метод. Столбцы Неявные флаги и Флаги содержат битовые маски, описывающие метод (например, является ли метод общим или закрытым). Столбец Имя содержит указатель имени метода из кучи строк. Столбец Сигнатура содержит указатель определения сигнатуры метода в куче больших двоичных объектов.

Среда выполнения вычисляет нужный относительный адрес из столбца RVA в третьей строке и возвращает этот адрес JIT-компилятору, который затем переходит к новому адресу. JIT-компилятор продолжает обрабатывать код MSIL по новому адресу до тех пор, пока не найдет другую лексему метаданных, и затем процесс повторяется заново.

Благодаря метаданным среда выполнения имеет доступ к любым сведениям, необходимым для загрузки кода пользователя и его преобразования в инструкции машинного кода. Таким образом, метаданные позволяют использовать файлы с самоописанием и — совместно с системой общих типов — межъязыковое наследование.

См. также

Основные понятия

Метаданные и компоненты с самоописанием

Процесс управляемого выполнения