Verwenden von Metadaten zur Laufzeit
Zum besseren Verständnis von Metadaten und ihrer Rolle in Common Language Runtime kann es hilfreich sein, ein einfaches Programm zu schreiben, das zeigt, wie Metadaten das Verhalten der Laufzeit beeinflussen. Folgendes Codebeispiel zeigt zwei Methoden innerhalb der Klasse MyApp
. Die Main
-Methode ist der Einstiegspunkt des Programms, während die Add
-Methode einfach die Summe zweier Ganzzahlargumente zurückgibt.
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);
}
}
Beim Ausführen des Codes lädt Common Language Runtime das Modul in den Speicher und fragt die Metadaten für diese Klasse ab. Nach dem Laden analysiert Common Language Runtime ausführlich den MSIL (Microsoft Intermediate Language)-Stream der Methode, um ihn in schnelle systemeigene Anweisungen zu konvertieren. Common Language Runtime verwendet einen JIT (Just-In-Time)-Compiler, um bei Bedarf jeweils für eine Methode die MSIL-Anweisungen in systemeigenen Maschinencode zu konvertieren.
Das folgende Beispiel zeigt einen Teil der MSIL, die aus der Main
-Funktion des vorherigen Codes erstellt wurde. Sie können die MSIL und die Metadaten aus jeder .NET-Anwendung mithilfe des MSIL Disassembler-Tools (Ildasm.exe) anzeigen.
.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 */
Der JIT-Compiler liest die MSIL der ganzen Methode, analysiert sie ausführlich und generiert effiziente, systemeigene Anweisungen für diese Methode. Bei IL_000d
wird ein Metadatentoken für die Add
-Methode (/*
06000003 */
) angetroffen. Common Language Runtime verwendet dieses Token, um die dritte Zeile der MethodDef-Tabelle abzufragen.
Folgende Tabelle zeigt einen Teil der MethodDef-Tabelle, welche die Add
-Methode beschreibt und auf die das Metadatentoken verweist. Obwohl es in dieser Assembly auch andere Metadatentabellen gibt, die jeweils ihre eigenen, eindeutigen Werte besitzen, wird hier nur diese Tabelle erläutert.
Zeile | RVA (Relative Virtuelle Adresse) | ImplFlags | Flags | Name (Zeigt auf Zeichenfolgenheap.) | Signatur (Zeigt auf BLOB-Heap.) |
---|---|---|---|---|---|
1 |
0x00002050 |
IL Verwaltet |
Public ReuseSlot SpecialName RTSpecialName .ctor |
.ctor (constructor) |
|
2 |
0x00002058 |
IL Verwaltet |
Public Static ReuseSlot |
Main |
String |
3 |
0x0000208c |
IL Verwaltet |
Public Static ReuseSlot |
Add |
int, int, int |
Jede Spalte der Tabelle enthält wichtige Informationen über Ihren Code. Über die RVA-Spalte kann Common Language Runtime die Startspeicheradresse der MSIL berechnen, die diese Methode definiert. Die ImplFlags-Spalte und die Flags-Spalte enthalten Bitmasken, welche die Methode beschreiben (z. B., ob es sich um eine öffentliche oder eine private Methode handelt). Die Name-Spalte gibt den Namen der Methode aus dem String-Heap an. Die Spalte Signatur gibt die Definition der Signatur der Methode im BLOB-Heap an.
Common Language Runtime berechnet die gewünschte Offset-Adresse aus der RVA-Spalte in der dritten Zeile und gibt diese Adresse an den JIT-Compiler zurück, der anschließend zur neuen Adresse übergeht. Der JIT-Compiler fährt mit der Verarbeitung der MSIL an der neuen Adresse fort, bis er erneut auf ein Metadatentoken trifft und der Prozess wiederholt wird.
Mithilfe von Metadaten stehen Common Language Runtime alle Informationen zur Verfügung, die benötigt werden, um den Code zu laden und in systemeigene Maschinenanweisungen zu verarbeiten. Auf diese Weise bilden Metadaten selbstbeschreibende Dateien und ermöglichen zusammen mit dem allgemeinen Typsystem sprachübergreifende Vererbung.
Siehe auch
Konzepte
Kompilieren in MSIL
Kompilieren von MSIL in systemeigenen Code