Metaadatok és önleíró összetevők
Korábban az egyik nyelven írt szoftverösszetevő (.exe vagy .dll) nem tudta könnyen használni egy másik nyelven írt szoftverösszetevőt. A COM egy lépést tett a probléma megoldása felé. A .NET még egyszerűbbé teszi az összetevők együttműködését azáltal, hogy lehetővé teszi a fordítók számára, hogy további deklaratív információkat bocsáthassanak ki az összes modulba és szerelvényekbe. Ezek az úgynevezett metaadatok segítenek az összetevőknek a zökkenőmentes interakcióban.
A metaadatok olyan bináris információk, amelyek a programot leíró bináris információk, amelyeket egy közös nyelvi futtatókörnyezeti hordozható végrehajtható fájlban (PE) vagy a memóriában tárolnak. Amikor egy PE-fájlba fordítja a kódot, a rendszer metaadatokat szúr be a fájl egyik részébe, a kód pedig köznapi köztes nyelvre (CIL) lesz konvertálva, és a fájl egy másik részébe lesz beszúrva. A modulban vagy szerelvényben definiált és hivatkozott összes típust és tagot a metaadatok ismertetik. A kód végrehajtásakor a futtatókörnyezet betölti a metaadatokat a memóriába, és arra hivatkozik, hogy információkat derítsen fel a kód osztályairól, tagjairól, örökléséről stb.
A metaadatok a kódban definiált összes típust és tagot nyelvsemleges módon írják le. A metaadatok a következő információkat tárolják:
A szerelvény leírása.
Identitás (név, verzió, kultúra, nyilvános kulcs).
Az exportált típusok.
Egyéb szerelvények, amelyektől ez a szerelvény függ.
A futtatáshoz szükséges biztonsági engedélyek.
A típusok leírása.
Név, láthatóság, alaposztály és implementált felületek.
Tagok (metódusok, mezők, tulajdonságok, események, beágyazott típusok).
Attribútumok.
- További leíró elemek, amelyek módosítják a típusokat és a tagokat.
A metaadatok előnyei
A metaadatok az egyszerűbb programozási modell kulcsai, és szükségtelenné teszi az interfészdefiníciós nyelv (IDL) fájljait, fejlécfájljait vagy bármely külső összetevő-referenciametódus használatát. A metaadatok lehetővé teszik, hogy a .NET-nyelvek automatikusan, nyelvsemleges módon írjanak le magukról, a fejlesztő és a felhasználó által nem látott módon. Emellett a metaadatok attribútumok használatával bővíthetők. A metaadatok a következő főbb előnyöket biztosítják:
Önleíró fájlok.
A gyakori nyelvi futtatókörnyezeti modulok és szerelvények önleírók. A modul metaadatai mindent tartalmaznak, ami egy másik modullal való interakcióhoz szükséges. A metaadatok automatikusan biztosítják az IDL funkcióit a COM-ban, így egy fájlt használhat a definícióhoz és a megvalósításhoz is. A futtatókörnyezeti modulok és szerelvények nem is igényelnek regisztrációt az operációs rendszerrel. Ennek eredményeképpen a futtatókörnyezet által használt leírások mindig a lefordított fájl tényleges kódját tükrözik, ami növeli az alkalmazás megbízhatóságát.
Nyelvi együttműködés és egyszerűbb összetevőalapú kialakítás.
A metaadatok a lefordított kódhoz szükséges összes információt biztosítják ahhoz, hogy egy osztályt egy másik nyelven írt PE-fájlból örököljön. Bármely osztály egy példányát bármilyen felügyelt nyelven (bármely olyan nyelven, amely a közös nyelvi futtatókörnyezetet célozza) anélkül hozhat létre példányt, hogy explicit rendezéssel vagy egyéni együttműködési kóddal kellene foglalkoznia.
Attribútumok.
A .NET lehetővé teszi bizonyos metaadatok, úgynevezett attribútumok deklarálását a lefordított fájlban. Az attribútumok a .NET-ben találhatók, és részletesebben szabályozhatók, hogyan viselkedik a program futásidőben. Emellett saját egyéni metaadatokat is kibocsáthat .NET-fájlokba felhasználó által definiált egyéni attribútumok használatával. További információ: Attribútumok.
Metaadatok és a PE-fájlstruktúra
A metaadatokat egy .NET hordozható végrehajtható fájl (PE) egyik szakaszában tárolja a rendszer, míg a közös köztes nyelvet (CIL) a PE-fájl egy másik szakaszában tárolja a rendszer. A fájl metaadat-része táblázat- és halom adatstruktúrák sorozatát tartalmazza. A CIL rész olyan CIL- és metaadat-jogkivonatokat tartalmaz, amelyek a PE-fájl metaadat-részére hivatkoznak. Metaadat-jogkivonatokkal találkozhat, ha például az IL-szétszerelt eszközt (Ildasm.exe) használja a kód CIL-jének megtekintéséhez.
Metaadattáblák és halom
Minden metaadattábla információkat tartalmaz a program elemeiről. Az egyik metaadattábla például a kód osztályait írja le, egy másik tábla pedig a mezőket stb. Ha a kódban tíz osztály szerepel, az osztálytábla több tíz sorból áll, egy-egy osztályhoz. A metaadattáblák más táblákra és halmokra hivatkoznak. Az osztályok metaadattáblája például a metódusok táblára hivatkozik.
A metaadatok emellett négy halomstruktúrában tárolják az információkat: sztring, blob, felhasználói sztring és GUID. A névtípusokhoz és tagokhoz használt összes sztring a sztring halomba kerül. A metódustáblák például nem tárolják közvetlenül egy adott metódus nevét, hanem a metódusnak a sztringben tárolt nevére mutatnak.
Metaadat-jogkivonatok
Az egyes metaadattáblák minden sora egyedileg van azonosítva a PE-fájl CIL-részében egy metaadat-jogkivonattal. A metaadat-jogkivonatok fogalmilag hasonlítanak a CIL-ben megmaradó, egy adott metaadattáblára hivatkozó mutatókhoz.
A metaadat-jogkivonat egy négy bájtos szám. A felső bájt azt a metaadattáblát jelöli, amelyre egy adott jogkivonat hivatkozik (metódus, típus stb.). A fennmaradó három bájt adja meg a metaadat-tábla azon sorát, amely megfelel a leírt programozási elemnek. Ha a C#-ban definiál egy metódust, és pe-fájlba fordítja, a következő metaadat-jogkivonat létezhet a PE-fájl CIL-részében:
0x06000004
A felső bájt (0x06
) azt jelzi, hogy ez egy MethodDef-jogkivonat . Az alsó három bájt (000004
) arra utasítja a közös nyelvi futtatókörnyezetet, hogy a MethodDef tábla negyedik sorában keresse meg a metódusdefiníciót leíró információkat.
Metaadatok pe-fájlon belül
Amikor egy programot lefordítanak a közös nyelvi futtatókörnyezethez, a program egy három részből álló PE-fájllá alakítja. Az alábbi táblázat az egyes részeket ismerteti.
PE szakasz | A PE szakasz tartalma |
---|---|
PE fejléc | A PE-fájl fő szakaszainak indexe és a belépési pont címe. A futtatókörnyezet ezen információk alapján azonosítja a fájlt PE-fájlként, és meghatározza, hogy hol kezdődik a végrehajtás a program memóriába való betöltésekor. |
CIL-utasítások | A Microsoft köztes nyelvi utasításai (CIL), amelyek a kódot alkotják. A CIL számos utasítását metaadat-jogkivonatok kísérik. |
Metaadatok | Metaadattáblák és halom. A futtatókörnyezet ebben a szakaszban rögzíti a kód minden típusával és tagával kapcsolatos információkat. Ez a szakasz egyéni attribútumokat és biztonsági információkat is tartalmaz. |
Metaadatok futásidejű használata
A metaadatok és a közös nyelvi futtatókörnyezetben betöltött szerepének jobb megértése érdekében hasznos lehet egy egyszerű program létrehozása és a metaadatok futásidejének befolyásolása. Az alábbi példakód két metódust mutat be egy úgynevezett MyApp
osztályon belül. A Main
metódus a program belépési pontja, míg a Add
metódus egyszerűen két egész argumentum összegét adja vissza.
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);
}
}
A kód futtatásakor a futtatókörnyezet betölti a modult a memóriába, és áttekinti az osztály metaadatait. A betöltés után a futtatókörnyezet átfogó elemzést végez a metódus közös köztes nyelvű (CIL) streamjéről, hogy gyors natív gépi utasításokká alakítsa azt. A futtatókörnyezet egy igény szerinti (JIT) fordítóval konvertálja a CIL-utasításokat natív gépkóddá, szükség szerint egy módszerrel.
Az alábbi példa az előző kód Main
függvényéből előállított CIL egy részét mutatja be. A CIL-t és a metaadatokat bármely .NET-alkalmazásból megtekintheti a CIL-szétszerelési eszközzel (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 */
A JIT-fordító beolvassa a teljes metódushoz tartozó CIL-t, alaposan elemzi, és hatékony natív utasításokat hoz létre a metódushoz. Ekkor IL_000d
megjelenik a Add
metódus (/*
06000003 */
) metaadat-jogkivonata, és a futtatókörnyezet a tokent használja a MethodDef tábla harmadik sorának megtekintéséhez.
Az alábbi táblázat a metódust leíró Add
metaadat-jogkivonat által hivatkozott MethodDef tábla egy részét mutatja be. Bár más metaadattáblák is léteznek ebben a szerelvényben, és saját egyedi értékekkel rendelkeznek, csak ezt a táblát tárgyaljuk.
Sor | Relatív virtuális cím (RVA) | ImplFlags | Zászlók | Név (A sztring halomra mutat.) |
Aláírás (A blob halomra mutat.) |
---|---|---|---|---|---|
0 | 0x00002050 | IL Felügyelt |
Nyilvános ReuseSlot Speciális név RTSpecialName .ctor |
.ctor (konstruktor) | |
2 | 0x00002058 | IL Felügyelt |
Nyilvános Statikus ReuseSlot |
Elsődleges | Sztring |
3 | 0x0000208c | IL Felügyelt |
Nyilvános Statikus ReuseSlot |
Hozzáadás | int, int, int |
A tábla minden oszlopa fontos információkat tartalmaz a kódról. Az RVA oszlop lehetővé teszi, hogy a futtatókörnyezet kiszámítsa a metódust meghatározó CIL kezdő memóriacímét. Az ImplFlags és a Flags oszlop bitmaszkokat tartalmaz, amelyek a metódust írják le (például hogy a metódus nyilvános vagy privát). A Név oszlop indexeli a metódus nevét a sztring halomból. Az Aláírás oszlop indexeli a metódus aláírásának definícióját a blob halomban.
A futtatókörnyezet kiszámítja a kívánt eltolási címet a harmadik sorban lévő RVA oszlopból, és visszaadja ezt a címet a JIT-fordítónak, amely ezután az új címre tér vissza. A JIT-fordító addig dolgozza fel a CIL-t az új címen, amíg egy másik metaadat-jogkivonattal nem találkozik, és a folyamat meg nem ismétlődik.
A metaadatok használatával a futtatókörnyezet hozzáfér a kód betöltéséhez és natív gépi utasításokba való feldolgozásához szükséges összes információhoz. Ily módon a metaadatok lehetővé teszik az önleíró fájlokat, és a gyakori típusrendszerrel együtt a nyelvközi öröklést.
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: