Магистрант
Керуенбаева К.М.
Кызылординский
государственный университет имени Коркыт Ата, Казахстан
Исполнительная среда CLR, как динамический механизм каркаса Framework .Net
Наиболее революционным изобретением Framework .Net явилось создание исполнительной среды CLR. С ее
появлением процесс написания и выполнения приложений становится принципиально
другим.
Компиляторы языков программирования, включенные в Visual Studio .Net, создают модули на промежуточном языке MSIL (Microsoft Intermediate
Language), называемом
далее просто - IL. Фактически компиляторы создают так называемый управляемый модуль - переносимый исполняемый файл
(Portable Executable или PE-файл). Этот файл содержит код на IL и метаданные - всю необходимую информацию как для CLR, так и конечных пользователей, работающих с
приложением.
PE-файл, имеющий уточнение exe, хотя и
является exe-файлом, но это не совсем обычный, исполняемый Windows, файл. При
его запуске он распознается как специальный PE-файл и передается CLR для обработки. Исполнительная среда начинает работать
с кодом, в котором специфика исходного языка программирования исчезла. Код на
IL начинает выполняться под управлением CLR (по этой
причине код называется управляемым).
Исполнительную среду можно рассматривать как своеобразную виртуальную
IL-машину. Эта машина транслирует "на лету" требуемые для исполнения
участки кода в команды реального процессора, который в действительности и
выполняет код.
Отделение каркаса от студии явилось
естественным шагом. Каркас Framework .Net перестал
быть частью студии, а стал надстройкой над операционной системой. Теперь
компиляция и создание PE-модулей на IL отделено от выполнения, и эти процессы
могут быть реализованы на разных платформах. В состав CLR
входят трансляторы JIT (Just In Time Compiler), которые и выполняют трансляцию
IL в командный код той машины, где установлена и функционирует исполнительная
среда CLR. Конечно, в первую очередь Microsoft
реализовала CLR и FCL для
различных версий Windows, включая Windows 98/Me/NT 4/2000, 32 и 64-разрядные
версии Windows XP и семейство .Net Server. Для операционных систем Windows CE и
Palm разработана облегченная версия Framework .Net.
В 2001 году ECMA (Европейская ассоциация
производителей компьютеров) приняла язык программирования C#, CLR и FCL в качестве стандарта,
так что Framework .Net уже функционирует на многих
платформах, отличных от Windows. Он становится свободно распространяемой
виртуальной машиной. Это существенно расширяет сферу его применения.
Производители различных компиляторов и сред разработки программных продуктов
предпочитают теперь также транслировать свой код в IL, создавая модули в
соответствии со спецификациями CLR. Это обеспечивает
возможность выполнения их кода на разных платформах.
Microsoft использовала получивший широкое
признание опыт виртуальной машины Java, улучшив процесс за счет того, что, в
отличие от Java, промежуточный код не интерпретируется исполнительной средой, а
компилируется с учетом всех особенностей текущей платформы. Благодаря этому
создаются высокопроизводительные приложения.
Следует отметить, что CLR,
работая с IL-кодом, выполняет достаточно эффективную оптимизацию и, что не
менее важно, защиту кода. Зачастую нецелесообразно выполнять оптимизацию на
уровне создания IL-кода - она иногда может не улучшить, а ухудшить ситуацию, не
давая CLR провести оптимизацию на нижнем уровне, где
можно учесть даже особенности процессора.
Если у вас есть готовый PE-файл, то иногда полезно
анализировать его IL-код и связанные с ним метаданные.
В состав Framework SDK входит дизассемблер - ildasm,
выполняющий дизассемблирование PE-файла и показывающий метаданные,
а также IL-код с комментариями в наглядной форме.
Переносимый исполняемый PE-файл является
самодокументируемым файлом и, как уже говорилось, содержит и код, и метаданные, описывающие код. Файл начинается с манифеста и
включает в себя описание всех классов, хранимых в PE-файле, их свойств,
методов, всех аргументов этих методов - всю необходимую CLR
информацию. Поэтому помимо PE-файла не требуется никаких дополнительных файлов
и записей в реестр - вся нужная информация извлекается из самого файла. Среди
классов библиотеки FCL имеется класс Reflection, методы которого позволяют извлекать
необходимую информацию. Введение метаданных не
только важная техническая часть CLR, но это также
часть новой идеологии разработки программных продуктов. Мы увидим, что и на
уровне языка C# самодокументированию уделяется большое внимание.
Мы увидим также, что при проектировании
класса программист может создавать собственные атрибуты, добавляемые к метаданным PE-файла. Клиенты этого класса могут, используя
класс Reflection, получать эту дополнительную
информацию, и на ее основании принимать соответствующие решения.
Дизассемблер структурирует информацию, хранимую в метаданных, и показывает ее в типичном формате дерева. Как
обычно, это дерево можно сжимать или раскрывать, демонстрируя детали класса.
Значки, приписываемые каждому узлу дерева, характеризуют тип узла - класс,
свойство, метод, описание. Двойной щелчок кнопки мыши на этом узле позволяет
раскрыть его. При раскрытии метода можно получить его код.
Еще одной важной особенностью
построения CLR является то, что исполнительная среда
берет на себя часть функций, традиционно входящих в ведение разработчиков
трансляторов, и облегчает тем самым их работу. Один из таких наиболее значимых
компонентов CLR - сборщик мусора
(Garbage Collector). Под сборкой мусора понимается освобождение памяти,
занятой объектами, которые стали бесполезными и не используются в дальнейшей
работе приложения. В ряде языков программирования (язык C/C++) память
освобождает сам программист, в явной форме отдавая команды как на создание, так
и на удаление объекта. Неизбежные ошибки программиста при работе с памятью
тяжелы по последствиям, и их крайне тяжело обнаружить. Как правило, объект
удаляется в одном модуле, а необходимость в нем обнаруживается в другом,
далеком модуле. Обоснование того, что программист не должен заниматься
удалением объектов, а сборка мусора должна стать частью исполнительной среды,
дано достаточно давно.
В CLR эта идея
реализована в полной мере. Задача сборки мусора снята не только с
программистов, но и с разработчиков трансляторов, она решается в нужное время и
в нужном месте - исполнительной средой, ответственной за выполнение вычислений.
Данные, удовлетворяющие требованиям CLR и
допускающие сборку мусора, называются управляемыми данными.
В C# модуль, использующий неуправляемые данные (указатели, адресную арифметику),
должен быть помечен как небезопасный (unsafe), и эти данные должны быть четко
зафиксированы. Исполнительная среда, не ограничивая возможности языка и
программистов, вводит определенную дисциплину в применении потенциально опасных
средств языков программирования.
Что происходит, когда при вызове некоторой
функции (процедуры) обнаруживается, что она не может нормальным образом
выполнить свою работу? Возможны разные варианты обработки такой ситуации.
Функция может возвращать код ошибки или специальное значение типа HResult, может выбрасывать исключение, тип
которого характеризует возникшую ошибку. В CLR
принято во всех таких ситуациях выбрасывать исключение. Косвенно это влияет и
на язык программирования. Выбрасывание исключений наилучшим образом согласуется
с исполнительной средой. В языке C# выбрасывание исключений, их дальнейший
перехват и обработка - основной рекомендуемый способ обработки исключительных ситуаций.
У CLR есть свое
видение того, что представляет собой тип. Есть формальное описание общей системы типов CTS - Common Type System. В
соответствии с этим описанием, каждый тип, помимо полей, методов и свойств,
может содержать и события. При возникновении событий в процессе работы с тем или иным объектом данного
типа посылаются сообщения, которые могут получать другие объекты. Механизм
обмена сообщениями основан на делегатах -
функциональном типе.
Исполнительная среда CLR
обладает мощными динамическими механизмами - сборки мусора, динамического
связывания, обработки исключительных ситуаций и событий. Все эти механизмы и их реализация в CLR созданы на основании практики существующих языков
программирования. Но уже созданная исполнительная среда, в свою очередь, влияет
на языки, ориентированные на использование CLR.
Поскольку язык C# создавался одновременно с созданием CLR,
то, естественно, он стал языком, наиболее согласованным с исполнительной
средой, и средства языка напрямую отображаются в средства исполнительной среды.
Уже говорилось, что каркас
Framework.Net облегчает межъязыковое взаимодействие. Для того чтобы
классы, разработанные на разных языках, мирно уживались в рамках одного
приложения, для их бесшовной отладки и возможности построения разноязычных
потомков они должны удовлетворять некоторым ограничениям. Эти ограничения
задаются набором общеязыковых спецификаций – CLS (Common
Language Specification). Класс, удовлетворяющий спецификациям
CLS, называется CLS-совместимым. Он доступен
для использования в других языках, классы которых могут быть клиентами или
наследниками совместимого класса.
Спецификации CLS точно определяют, каким набором встроенных
типов можно пользоваться в совместимых модулях.
Эти типы должны быть общедоступными для всех языков, использующих Framework.Net. В совместимых модулях
должны использоваться управляемые данные и выполняться
некоторые другие ограничения. Закрытая
часть класса может и не удовлетворять CLS. Классы,
от которых не требуется совместимость, могут использовать специфические
особенности языка программирования.
Литература
1. Троелсен Э.
С# и платформа .NET – СПб: Питер, 2003.
2.
Биллиг В.А. Основы
программирования на C#. – М.:ИНТУИТ.РУ, 2006.
3.
Павловская Т.А. C#: Программирование на языке высокого уровня. – СПб.:Питер, 2007.
4.
Нейгел К., Ивьен Б.,
Глин Дж. и др. C# 2005 для профессионалов. – М.:Вильямс, 2006.