Основи платформи .NET Framework
Зміст Платформа .NET. Складові частини CLI. Основи поняття .NET-додатків та середовища виконання .NET -компіляція. Загальна проміжна мова CIL. Поняття керованого коду. Загальна система типів CTS. Метадані. Міжмовна інтеграція у .NET. Збірки .NET. Just In Time (JIT) компіляція. Управління пам'яттю. Збирання сміття. Порівняння компонентних підходів COM та .NET.
Від COM до .NET За іронією долі платформа .NET Framework з'явилася у результаті зусиль, спрямованих на те, щоб спростити розробку COM-додатків. Тобто сталося так, що не зовсім вдала платформа COM була не просто підправлена чи виправлена, а фактично замінена новою – .NET Framework вважається новою платформою компонентного програмування від Microsoft.
Платформа .NET Framework. Трохи історії Розробка платформи почалася у 1998 році. Перша робоча назва – Project 42, потім була назва COM Object Runtime чи, скорочено, COR, пізніше Lightning, COM+ 2.0, Next Generation Web Services і, нарешті, Framework. Ще у 1998 році була представлена архітектура середовища виконання .NET – “віртуальної машини .NET” : "Більш ніяких GUID, ніяких HRESULT, ніяких IUnknown!”. Початкова назва середовища виконання – віртуальна система виконання VES(Virtual Execution System), пізніше почав використовуватись термін загальномовне середовище виконання (Common Language Runtime, CLR). 13 лютого 2002 року – представлено пакет .NET Framework. Загалом, .NET Framework – це пакет засобів для так званих програм нового покоління. Його ядром виступає CLR – “віртуальна машина .NET”, інструкції якої визначаються об'єктно-орієнтованою мовою CIL (Common Intermediate Language, загальна проміжна мова). Не менш важливим компонентом платформи .NET є Framework Class Library (FCL) – єдина бібліотека класів для всіх мов платформи .NET.
Платформа .NET Framework. Основні складові частини .NET Framework – це пакет засобів для так званих програм нового покоління Ядром .NET Framework виступає CLR (Common Language Runtime) – “віртуальна машина .NET”, інструкції якої визначаються об'єктно-орієнтованою мовою CIL (Common Intermediate Language, загальна проміжна мова). Другим важливим компонентом платформи .NET Framework є Framework Class Library (FCL) – єдина бібліотека класів для всіх мов платформи .NET.
Специфікація Microsoft загальної інфраструктури мов CLI. Складові частини CLI Складові частини CLI (Common Language Infrastructure): Загальна система типів CTS (Common Type System) – містить основні типи, що зустрічаються в розповсюджених мовах програмування. Загальна проміжна мова CIL (Common Intermediate Language). (Вона є цільовою мовою компіляторів, що орієнтуються на CLI). Віртуальна система виконання VES (або CLR) – відповідає за завантаження і виконання CIL-програм (віртуальна машина). Система метаданих (Metadata System) – описує збірки, типи у збірках. Зберігається в незалежному від конкретної мови програмування вигляді. Використовується для підтримки компонентної (у тому числі міжмовної) інтеграції. Загальна специфікація мов CLS (Common Language Specification) – аспекти сумісності мов, що є важливим для реалізації компіляторів (надмовні поняття: збірки, метадані; засади міжмовної інтеграції: створення типів, використання “зовнішніх” типів).
Специфікація Microsoft загальної інфраструктури мов (Common Language Infrastructure, CLI ) Окрім .NET Framework відомі й інші спроби реалізації CLI: платформа Mono компанії Ximian, проект Portable.NET. Крім того, Microsoft пропонує вихідні коди ще однієї своєї реалізації CLI під Windows та FreeBSD – це Shared Source CLI, для якої використовується також назва Rotor. Реалізації CLI та платформи:
Основи поняття .NET-додатків та середовища виконання Ключові специфікації: - CIL (Common Intermediate Language) — загальна проміжна мова;
- CTS (Common Type System) — загальна система типів;
- CLR (Common Language Runtime) — “віртуальна машина .NET”.
.NET-компіляція .NET-компілятор за вхідним кодом генерує байт-код (керований код), що складається з програмного коду (набору інструкцій) у проміжній мові CIL та метаданих. У .NET Framework результатом компіляції виступають PE-файли (Portable Executable) – .NET Framework розширює специфікацію PE-файлів, за рахунок чого програмісти .NET найчастіше мають справу зі знайомими розширеннями файлів EXE та DLL. Але у даному випадку це знайомі “незнайомці” – модулі керованого коду (байт-коди .NET). (Модулі із розширенням NETMODULE називають “сирими”. Вони не можуть, наприклад, окремо завантажуватись, а тим більше виконуватись).
Керований код .NET. Як запускається віртуальна машина .NET? CLR повністю контролює виконання байт-коду .NET (саме тому виконуваний .NET-код називається керованим – managed). Зокрема, CLR забезпечує різноманітні служби і серед них автоматичний збирач сміття. Windows, опрацьовуючи виконуваний .NET-файл, сканує таблицю імпорту та завантажує згадувані у ній бібліотеки, серед яких завжди є mscoree.dll (часто вона буває взагалі єдиною у таблиці імпорту, mscoree – абревіатура від Microsoft Component Object Runtime Execution Engine). Бібліотека mscoree.dll – це фасад CLR (фасад віртуальної машини .NET). А точка входу керованого коду (виконуваного .NET-файлу EXE чи DLL) є заглушкою з командою (інструкцією) передачі управління віртуальній машині .NET. (Одно- чи багатопроцесорний варіант CLR - mscorwks.dll, mscorksr.dll; JIT-компілятор mscojit.dll etc).
Загальна проміжна мова CIL Код у мові CIL (Common Intermediate Language) – це незалежний від процесора набір інструкцій, які, з одного боку, можна ефективно перетворити в машинний код, а з іншого боку – забезпечують об'єктну підтримку, зокрема, виклики методів об'єктів, а також забезпечують арифметичні та логічні операції, передачу управління, обробку виключень тощо. MS дизасемблер ildasm.exe забезпечує: - перегляд “асемблерного” коду CIL та метаданих;
- дизасемблювання байт-коду в “асемблерний” код.
MS асемблер ilasm exe: - забезпечує підтримку програмування у CIL -“асемблерній” мові.
Загальна система типів CTS – фундамент міжмовної взаємодії (1/2) Усі типи успадковуються від System.Object: - “усі типи є класами”;
- не має дивувати конструкція 7.ToString();
- дуже важливий для рефлексії метод GetType – тип (клас) Type надає широкий спектр методів рефлексії).
Атрибути – об'єкти, що прикріплюються до типів чи їх членів. (Декларативний стиль програмування). Регламентуються члени класів (поля, методи, властивості, події, вкладені методи), регламентуються успадкування типів (лінійне для класів та структур і множинне для інтерфейсів).
Загальна система типів CTS – фундамент міжмовної взаємодії (2/2) Value та reference типи: - value types – біти у стековій пам'яті, заборона на конструктори без параметрів (конструктори за замовчуванням):
- вбудовані типи;
- типи, що визначаються користувачем:
- enum, struct;
- System.DateTime, System.Decimal, System.Guid – “наперед” визначені типи FCL.
- reference types – посилання: вказівник + біти у динамічній пам'яті (купі), при цьому вказівник інкапсулює одночасно адресу та інформацію про тип.
- Порівняння: ідентичність (посилання на один і той самий об'єкт) та рівність (однакові біти у пам'яті) (.NET каже “ні” безтиповому підходу, адресній арифметиці. Є лише дві загальнодоступні операції над посиланнями: читання та занесення даного).
- Політика безпечності типів (контроль доступу з боку CLR).
- Автоматичне збирання сміття.
- boxing (пакування, обгортання), unboxing.
Типи .NET Framework – FCL (Framework Class Library ) та CLS-сумісність
.
.NET-компіляція. Метадані Метадані є засобом самоопису коду, зокрема, метадані містять інформацію про всі класи, визначені у вхідному коді (модулі), що дозволяє ефективно розв'язувати наступні важливі задачі компонентного проектування програм: - міжмовна інтеграція;
- віддалена взаємодія між об'єктами (. NET Remoting);
- механізми рефлексії (.NET Reflection);
- серіалізація даних (Serialization).
Метадані є абсолютно прозорими для програмістів.
Міжмовна інтеграція у .NET. Мовна безшовність .NET
Збірки .NET Збірки — фундаментальні одиниці, "будівельні" блоки .NET. Саме збірки при потребі завантажуються та виконуються віртуальною машиною. Саме зі збірками пов'язані механізм керування версіями та механізм захисту. "Повне ім'я" будь-якого типу в CIL прив'язане до збірки. Збірка (assembly) є логічним об'єднанням програмних модулів, ресурсних файлів, а також інших збірок . Про "склад" збірки можна дізнатись з її маніфесту, який є частиною метаданих. Збірка може розгортатись в каталозі проекту. Така збірка називається закритою, оскільки вона не є доступною для проектів в інших каталогах. Щоб забезпечити використання збірки різними додатками, її потрібно занести у кэш глобальних збірок GAC (Global Assembly Cache). (Збірки можуть бути також динамічними. Такі збірки створюються у пам'яті під час виконання проекту.)
Міжмовна інтеграція у .NET. Модулі .NET
.NET-компіляція. Метадані. Збірки .NET
Міжмовна інтеграція у .NET. Приклад. ( “Сервер у клієнтському процесі”, “внутрішній сервер”)
Міжмовна інтеграція .NET. Приклад. (Звичайний, “не серверний” клас у DLL).
Приклад віддаленої (remoting) взаємодії (з тим же серверним класом ServerObject)
Приклад віддаленої взаємодії (remoting)
Just In Time (JIT) компіляція у машинний код (компіляція за потребою, компіляція “на льоту”) Особливості JIT-компіляції: Саме компіляція (у машинний код), а не інтерпретація. Не вся програма (байт-код) компілюється. (Компіляція за потребою – враховується, що при виконанні програми не весь її код може бути використаним, а отже не весь варто компілювати). - Не використовувані збірки навіть не завантажуються, не го-ворячи вже про їх компіляцію. (Збірка – одиниця розгортання.)
- Спочатку (під час завантаження) для кожного з методів створюється спеціальна “заглушка”. При першому виклику метода заглушка забезпечує передачу управління JIT-компілятору, метод компілюється і заглушка змінюється так, щоб наступні виклики метода призводили до передачі управління отриманому машинному коду, що реалізує даний метод.
JIT-компіляція та строга типізація коду У процесі компіляції у машинний код CLR забезпечує перевірку, чи є код строго типізованим, тобто чи виконуються наступні вимоги: - усі посилання є, по-перше, типізованими і, по-друге – сумісними з тими даними, які адресуються відповідними вказівниками;
- для об'єкта викликаються тільки правильно визначені операції;
- посвідчення типів (“повні” імена типів з “префіксами” – іменами збірок) є коректними (“справжніми”).
Строга типізація дозволяє ізолювати об'єкти один від одного і унеможливити їх ненавмисне чи навмисне ушкодження. Це дуже важливо для безпеки коду. Саме строга типізація є підґрунтям застосування доменів, а також підходу до реалізації автоматичного збирача сміття.
Кероване виконання машинного коду. Використання служб Загальномовне середовище виконання (віртуальна машина .NET) надає інфраструктуру, яка забезпечує кероване (managed) виконання машинного коду: під час виконання машинного (керованого) коду віртуальна машина .NET забезпечує наступні служби: - збирання сміття;
- безпеки;
- взаємодії з некерованим кодом;
- віддаленої взаємодії;
- управління потоками;
- підтримки відстеження версій.
Управління пам'яттю. Збирання сміття Автоматичне управління пам'яттю це одна із служб, яку “віртуальна машина” (CLR) надає у процесі керованого виконання. Зокрема, вирішуються ключові проблеми управління пам'яттю: - “витікання пам'яті”;
- “висячі посилання”.
Підхід .NET наполягає на тому, щоб відмовитись від явного управління пам'яттю, натомість пропонується використовувати екземпляри reference типів (найчастіше класів).
Збирання сміття (garbage collection, GC). Основні поняття “Керована” купа – неперервна (без дефрагментацій!) область адресного простору (забезпечується висока швидкість виділення пам'яті). “Корені”. Кожен корінь або посилається на об'єкт (типізований!), який міститься у керованій купі, або має порожнє значення. (Корені пов'язані з глобальними та статичними об'єктами, локальними змінними, параметрами у стеку). Покоління. (0-, 1-, 2-покоління). Ущільнення пам'яті. Метод Finalize, черга фіналізації.
Порівняння компонентних підходів COM та .NET. Ключова розбіжність – віртуалізація (virtualization) контрактів .NET - Контракти компонентів COM є "фізичними" ("двійковими"), звідки жорсткі умови міжкомпонентних викликів: точні зміщення у таблиці віртуальних методів vtable, точна дисципліна стека (_stdcall), точний формат вказівників на інтерфейс тощо. Практична необхідність використання метазасобів для опису контрактів. (Два метазасоби: мова IDL та бібліотеки типів TLB).
- Контракти компонентів .NET є віртуалізованими – не використовується "фізичний" (“двійковий”) рівень, ніяких угод про представлення у пам'яті. Контракти представляються у форматі метаданих (metadata). (Прозорість метаданих).
- Інструментальні засоби читання та генерування метаданих (генерування прозоре, автоматичне).
- Для компонентів обов'язкове (автоматичне!) “супроводження” метаданими (на відміну від COM ).
- CIL абстрагований від “машинного рівня”, у ньому виклики компонентних методів посилаються на метадані з використанням звичайних імен, а не вказівників чи зміщень.
Додаток
Дизасемблер ildasm.exe. Метадані SOBj_.dll
Дизасемблер ildasm.exe. Метадані SOBj_.dll
Дизасемблер ildasm.exe. Метадані SOBj_.dll
Дизасемблер ildasm.exe. Метадані SOBj_.dll
Дизасемблер ildasm.exe. Метадані SOBj_.dll, CForm_. dll
Дизасемблер ildasm.exe. Маніфест файлу CForm_.exe
Дизасемблер ildasm.exe. Перегляд методу cmdCall_Click (файл CForm_.exe)
Самоопис керованого коду .NET. Механізм рефлексії Керований код .NET містить метадані (metadata), які представляють собою опис самого коду, зокрема опис усіх використаних у коді типів. .NET Framework, спираючись на метадані, забезпечує підтримку механізму рефлексії (reflection). У просторі імен System.Reflection.Emit надаються функції, які дозволяють отримувати дані про типи, що використані у збірці. Далі, за отриманими даними про типи, .NET Framework дозволяє динамічно (під час виконання програми) створювати об'єкти – екземпляри таких типів.
|