Dnes si rozebereme jádro .NET frameworku a ukáži vám MSIL. Současně předvedu jednoduchý přiklad v C# a to, jak vypadá rozložený do MSIL.

.NET framework stojí jako nadstavba nad operačním systémem. Obsahuje CLR (Common Language Runtime) zajištující základní funkcionalitu celého .NET frameworku. Na tomto Common Language Runtimu jsou postaveny všechny další základní knihovny a objekty sloužící například pro přístup k datům (ADO.NET, XML, SQL), k vícevláknovému zpracování aplikací (Threading) k přístupu do sítě a internetu (NET) a k zpracovávání, auditování a monitorování bezpečnosti aplikací (Security). Nad těmito knihovnami stojí už pouze:

a) Webové služby

  • samotné webové služby
  • webové formuláře
  • ASP.NET

b) Uživatelské rozhraní

  • controls (tlačítka, seznamy, posuvníky)
  • GDI+ (sloužící pro lepší manipulaci s grafikou, .NET framework totiž podporuje nativně souborové formáty JPG, GIF atd., které si již můžeme sami programově vytvářet)
  • služby pro tvorbu klasických desktopových aplikací

Tyto knihovny, jak již bylo zmíněno, tvoří srdce .NET frameworku a jsou přístupné z jakéhokoli jazyka platformy .NET. Přímo Microsoftem jsou podporované čtyři jazyky: Visual Basic, C++, JScript a nový, velmi perspektivní jazyk C#. Jak jsem již zmínil v minulém článku, tato sestava není konečná, neboť je pouze na vývojářích třetích stran, jak tuto sestavu rozšíří. Všechny jazyky pracující na platformě .NET však musí splňovat určité předpoklady dané CLS (Common Language Specification), která obsahuje soubory vlastností a požadavků kladených na tyto jazyky.

MSIL

Další pojem, který bych chtěl vysvětlit je MSIL (Microsoft Intermediate Language) a Managed Code. Vždy, když spouštíte jakýkoli program napsaný pro .NET framework, o jehož provádění se stará CLR, je tento kód řízený (managed), v opačném případě je neřízený (unmanaged). Jediný kompilátor, který dokáže generovat čistý neřízený kód, je kompilátor pro C++. Výstupem každého kompilátoru na platformě .NET při generování řízeného kódu je tzv. MSIL. Je to procesorově nezávislý jazyk podobající se assembleru. Jeho zavedení je snahou Microsoftu zvýšit přenositelnost kódu na různé druhy hardwaru, na kterých běží Windows. Jsou to například různá PDA zařízení, mobilní telefony, tablety, desktopové počítače, notebooky, servery s procesory Alpha a mj. i nové 64bitové procesory. Do dnešní doby jsme byli nuceni zdrojový kód kompilovat pro každý takový hardware zvlášť. Pokusy o vytvoření nezávislého přenositelného kódu jsou již známé z minulosti – Microsoftem navržený PE formát (portable executable) nebo byte kód firmy Sun sloužící pro běh aplikací napsaných v Javě a běžících nad „virtuálním strojem“ (obdoba CLR).

Ačkoli je MSIL velmi podobný assembleru, neexistuje v současné době žádný procesor, který by ho uměl nativně vykonávat. Proto ho musíte před spuštěním přeložit do strojového kódu za pomocí kompilátoru označovaného jako JITter. Je to tzv. Just-in-time kompilátor. Existují 3 druhy Just-in-time kompilace:

1) Kompilace v době instalace – toto řešení však není pravá Just-in-time kompilace, protože se neprovádí při spouštění programu, ale již při jeho instalaci. To poskytuje výhodu toho, že se MSIL kód překládá pouze jednou a pak při každém spouštění už spouštíme strojový kód. Nevýhoda je v tom, že pokud nainstalovaný exe nebo dll soubor zkopírujete na počítač třeba Alpha procesorem, pak vám aplikace nepůjde spustit. Je tedy nutná opětovná instalace.

2) Skutečný JITter – .NET aplikace je spuštěna a MSIL kód je najednou přeložen do strojového kódu. Velkou výhodou je, že tento kód je .NET frameworkem přímo optimalizovaný na ten konkrétní stroj, na kterém byl spuštěn a může proto naplno využít jeho potenciál. Nevýhodou je však přítomnost obou verzí programu v paměti – jak strojový, tak MSIL kód. Ten je však odstraněn hned po dokončení kompilace. Druhá nevýhoda je výkonnostní režie JITtru, která je potřeba při spouštění aplikace. Jakmile je však kód přeložen do strojového kódu, je prováděn stejnou rychlostí jako jakýkoli jiný strojový kód.

3) Ekonomický JITter – je to skutečný JITter, ale při jeho překladu MSIL do strojového kódu jsou vypnuty všechny optimalizace jak pro zmenšení, tak pro zrychlení programu. Druhá jeho vlastnost je inteligentní překlad programu a to tak, že nepřeloží celý program najednou (viz 2), ale jenom jeho právě prováděnou část. Volání funkcí, které zatím nejsou přeloženy, nahradí tzv. stubem (krátký kód), který se navenek tváří jako plnohodnotná funkce, avšak při jejím zavolání dojde k přeložení další části programu a jejímu vykonání.

A abych vás navnadil na další experimenty s .NET frameworkem, uvedu zde malý příklad pro otestování výše zmíněného.

Napsal jsem malý program v jazyce C#. Je to konzolová aplikace a k popisu nemusím asi mnoho psát.

class MSILTest

{

        public static void Main()

       {

                System.Console.Write(„Prvni pokus s .NET frameworkem“);

       }

 }

Programátorům v C++ bude připadat k nerozeznání od jejich jazyka, avšak ani pro jiné programátory není těžký k pochopení. Sami si jej můžete zkusit např. v poznámkovém bloku napsat a otestovat. Překládat jej budete pomocí překladače pro jazyk C# jménem csc.exe. Zmíněný překladač se nachází v .NET frameworku SDK. Pokud ho již máte nainstalovaný, můžete zapsat na příkazovém řádku csc msiltest.cs a měl by se vám vytvořit soubor msiltest.exe.

Když se ho pokusíte spustit, nastane postup, který jsem popisoval výše. Dojde k překladu z MSIL do nativního kódu procesoru pomocí Just-in-time kompilátoru, ale jelikož je tento program velice krátký, nepoznáte žádnou časovou prodlevu. Abyste se přesvědčili, že jde opravdu o kód v MSIL, využijte nástroj ILDasm.exe, což je standardní MSIL disassembler, dokáže však přehledně zobrazit informace v souboru.

Poklepáním na poslední položku, funkci Main, si můžete zobrazit zdrojový MSIL kód.

 

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět