Программирование: встречаем C# и Mono

Автор: (C) Ariel Ortiz Ramirez
Перевод: (C) Андрей Киселев


C# (читается как "Си шарп") является новым объектно-ориентированным языком программирования, разработанным для максимально удобного использования всех возможностей платформы Microsoft .NET. Он во многом похож на другие популярные объектно-ориентированные языки, такие как C++ и Java, но имеет и свои отличительные особенности.

Благодаря появлению проекта Mono, в Linux тоже есть возможность разрабатывать приложения на C#. Mono - это свободно распространяемая реализация платформы .NET. Ниже я постараюсь рассказать об основных элементах Mono.

Проект Mono

В настоящее время в рамках этого проекта реализованы два стандарта: язык программирования C# (Стандарт ECMA-334) и Инфраструктура Обобщенного Языка Программирования (CLI) (Стандарт ECMA-335). Обе спецификации были разработаны в корпорации Microsoft и представлены ECMA (Европейская Ассоциация Производителей Компьютеров) в октябре 2000 года. Формальное одобрение было получено в декабре 2001 года и эти предложения, возможно, станут стандартами ISO (благодаря соглашению о согласовании работы ["fast-track"], существующему между ISO и ECMA) ближе к концу следующего года.

Проект Mono спонсируется компанией Ximian, той самой, которая дала нам графический рабочий стол GNOME. Лидер проекта -- мексиканский программист, главный технический директор Ximian - Мигель де Иказа (Miguel de Icaza). На мой взгляд разработчики, привлеченные к работе над проектом Mono, в очень короткое время проделали огромный объем работ. Между прочим, слово "Mono", в переводе с испанского, означает "обезьяна". А ребят из Ximian обезьяниичать учить не надо!

Привет, мир Mono!

Попробуем на примере простой программы разобраться в том, как взаимодействуют между собой различные компоненты Mono и языка C#. Перед тем как приступить к изучению, необходимо установить Mono у себя на компьютере (информацию об установке Mono вы найдете в разделе Ссылки).

На диаграмме, приведенной ниже, показан путь, который проходит программа на языке C# от компиляции до исполнения:

Здесь должна быть схема, которую можно посмотреть на http://gazette.linux.ru.net/lg84/misc/ortiz/using_mono.png.

Для начала рассмотрим простую программу на языке C# (классический "Привет мир"). Создайте в любом текстовом редакторе файл со следующим содержимым:

class Hello {
    public static void Main() {
        System.Console.WriteLine("Hello Mono World!");
    }
}

и сохраните его с именем hello.cs.

Программа состоит из класса Hello, который содержит метод Main. Этот метод представляет собой точку входа в программу, фактически то же самое, что и функция main в программах на языке C/C++. В этом примере метод Main выдает на стандартный вывод строку "Hello Mono World". (мне это напоминает java и совсем не напоминает C/C++, но в мире C# об этом говорить не принято? -- прим. ред.)

Теперь скомпилируем программу компилятором C# (называется он mcs), выполнив такую команду:

mcs hello.cs

В результате работы компилятора - в текущем каталоге должен появиться файл hello.exe. Пусть вас не сбивает с тольку расширение .exe файла. Это не исполняемый файл системы Windows, во всяком случае - расширение не определяет способ пользования файлом. В отличие от компиляторов C/C++, компилятор C# не создает машинный код. Создаваемый им двоичный файл - сборка, содержит метаданные и инструкции на промежуточном, платформо-независимом языке (intermediate language (IL)). Это означает, что при запуске такой программы, она должна пройти этап дополнительной трансляции кода из промежуточного языка в машинные инструкции того процессора, на котором исполняется программа. Эта последняя стадия трансляции выполняется виртуальной машиной, которая определяется Инфраструктурой Обобщенного Языка Программирования (Common Language Infrastructure - CLI). CLI определяет объектно-ориентированную среду времени исполнения, поддерживающую базовую библиотеку классов, динамическую подгрузку и связывание классов, многопоточное исполнение, трансляцию "на лету" и механизмы автоматического управления памятью. В реализации спецификации от Microsoft - CLI обычно называется как Common Language Runtime - Среда Выполнения для Обобщенного Языка Программирования (CLR). Можно смело утверждать, что CLR является надмножеством для CLI, поскольку она содержит некоторые расширения, не являющиеся частью CLI.

Чтобы запустить наш скомпилированный пример необходимо воспользоваться программой mono, которая представляет собой виртуальную машину Mono. В результате выполнения следующей команды:

mono hello.exe

На стандартный вывод (окно терминала и т.п.) будет выведена строка:

Hello Mono World!

За кулисами

А теперь давайте "заглянем" внутрь скомпилированного файла - сборки. Программа monodis (Mono дизассемблер) выводит содержимое сборки в текстовом представлении. Введите следующую команду:

monodis hello.exe

Дизассемблер должен вывести нечто подобное:

 .assembly extern mscorlib
{
  .ver 0:0:0:0
}
 .assembly 'hello'
{
  .hash algorithm 0x00008004
  .ver  0:0:0:0
}
  .class private auto ansi beforefieldinit Hello
        extends [mscorlib]System.Object
  {

    // method line 1
    .method public hidebysig  specialname  rtspecialname
           instance default void .ctor()  cil managed
    {
        // Method begins at RVA 0x20ec
        // Code size 7 (0x7)
        .maxstack 8
        IL_0000: ldarg.0
        IL_0001: call instance void valuetype [corlib]System.Object::.ctor()
        IL_0006: ret
    } // end of method instance default void .ctor()

    // method line 2
    .method public static
           default void Main()  cil managed
    {
        // Method begins at RVA 0x20f4
        .entrypoint
        // Code size 11 (0xb)
        .maxstack 8
        IL_0000: ldstr "Hello Mono World!"
        IL_0005: call void class [corlib]System.Console::WriteLine(string)
        IL_000a: ret
    } // end of method default void Main()

  } // end of type Hello

В первом разделе находятся метаданные. Они содержат текущую версию программы, дополнительные ограничения по безопасности, информацию о локали и список внешних сборок, используемых данной сборкой. Все остальное - это код на промежуточном языке (IL). Здесь можно видеть два метода:

  1. Конструктор класса по-умолчанию - .ctor, который создается компилятором автоматически.
  2. Наш метод Main.

Как уже говорилось ранее, виртуальная машина использует JIT-компилятор (just-in-time - "на лету") для трансляции кода на промежуточном языке (IL) в машииный код. Трансляция производится только тогда, когда в этом возникает необходимость (отсюда и название "на лету" - just-in time). В нашем случае, для метода Main генерируется следующий машинный код (синтаксис языка ассемблера AT&T):

push   %ebp
mov    %esp,%ebp
sub    $0x30,%esp
push   $0x80c9eb0
mov    0x805462c,%eax
push   %eax
cmpl   $0x0,(%eax)
mov    (%eax),%eax
call   *0x94(%eax)
add    $0x8,%esp
mov    0x805462c,%eax
push   %eax
cmpl   $0x0,(%eax)
mov    (%eax),%eax
call   *0xb4(%eax)
add    $0x4,%esp
leave
ret

Кроме того, в состав Mono входит интерпретатор mint. Эта программа, вместо JIT-компиляции выполняет интерпретецию инструкций промежуточного языка (IL). Если говорить о скорости выполнения, то для нашего конкретного примера интерпретатор mint дает несколько более высокую скорость исполнения, поскольку не тратится время на компиляцию и размещение скомпилированного кода в памяти. Конечно же, машинный код, уже размещенный в памяти, выполняется намного быстрее чем интерпретация IL. В настоящее время JIT-компилятор Mono существует только для платформы x86. На других платформах следует использовать интерпретатор. Чтобы увидеть результат работы интерпретатора, выполните следующую команду:

mint hello.exe

Если вы хорошо знакомы с Java, то вы обнаружите, что эти технологии в значительной степени схожи. И это действительно так. Виртуальная машина является ключевым фактором в достижении независимости от аппаратной платформы. Это означает, что я могу написать и скомпилировать программу под Linux, используя Mono, а затем запустить ее под Windows с установленной .NET Framework. И при этом не потребуется переписывать или перекомпилировать исходный код. Однако, в противовес виртуальной машине Java, прочно привязанной к одному языку программирования, спецификация CLI (Инфраструктура Обобщенного Языка Программирования) провозглашает не только независимость от аппаратной платформы, но и независимость от языка программирования! Под Windows имеется целый ряд языков программирования, нацеленных на CLR (Среда Выполнения для Обобщенного Языка Программирования). Наиболее важные, являющиеся частью среды разработки Microsoft Visual Studio .NET: Visual Basic .NET, JScript .NET, Managed C++ и C#. Среди других языков программирования от сторонних производителей, поддерживающих новую технологию .NET, можно назвать APL, COBOL, Eiffel, Forth, Fortran, Haskell, Mercury, Mondrian, Oberon, Pascal, Perl, Python, RPG, Scheme и SmallScript. Что касается проекта Mono, то на сегодняшний день в нем существует единственный язык программирования - это C#, но, вероятно в ближайшем будущем, мы увидим поддержку и других языков программирования.

Другая немаловажная часть CLI - это Common Type System - Общая Система Типов (CTS). CTS дает полное описание всех типов данных, поддерживаемых виртуальной машиной, включая порядок их взаимодействия и формат представления в области метаданных сборки. Важен тот факт, что не все языки программирования, следующие спецификации CLI, поддерживают полный список типов данных из CTS. Поэтому существует еще Common Language Specification - Спецификация Обобщенного Языка Ппрограммирования (CLS), определяющая минимальный набор типов, которые должны поддерживаться всеми языками программирования, следующими спецификации CLI. Это означает, что если мы создали класс, который использует только те качесва, которые доступны в CLS, то его можно будет использовать в программах на любом другом CLI-совместимом языке программирования. Вы можете написать реализацию класса на Eiffel, наследника на C# и использовать его в пограмме на Visual Basic.NET. Теперь такая совместимость стала реальностью.

О преимуществах

Используя платформу CLI, такую как Mono или .NET, вы приобретаете ряд очень важных преимуществ:

Кроме того, язык программирования C# дает еще ряд важных преимуществ:

Эти и другие проблемы C# я буду затрагивать более подробно в своих последующих публикациях.

Ссылки

http://www.go-mono.com/
Официальная домашняя страничка проекта Mono. Здесь вы найдете инструкции по установке.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/ deicazainterview.asp
Очень интересное интервью с Мигелем де Иказа о проекте Mono и использовании стандартов ECMA.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cscon/html/vco riCStartPage.asp
MSDN. Информация о языке программирования C#
http://www.ecma.ch/ecma1/STAND/ec ma-334.htm
Станларт ECMA-334. Спецификация языка C#.
http://www.ecma.ch/ecma1/STAND/ec ma-335.htm
Станларт ECMA-335. Инфраструктура Обобщенного Языка Программирования.

От переводчика: Не могу не привести интереснейшие ссылки на русскоязычные ресурсы, которыми я пользовался в процессе работы над документом.

http://www.dotsite.spb.ru/
Сайт целиком посвящен технологии .NET
http://www.javapower.ru/net/index.htm
Сайт посвященный Java, JavaScript, .Net и сопутствующим им технологиям.

Copyright (C) 2002, Ariel Ortiz Ramirez. Copying license http://www.linuxgazette.com/copying. html
Published in Issue 84 of Linux Gazette, November 2002

Команда переводчиков:
Владимир Меренков, Александр Михайлов, Иван Песин, Сергей Скороходов, Александр Саввин, Роман Шумихин, Александр Куприн, Андрей Киселев

Со всеми предложениями, идеями и комментариями обращайтесь к Сергею Скороходову ([email protected]). Убедительная просьба: указывайте сразу, не возражаете ли Вы против публикации Ваших отзывов в рассылке.