Содержание


Работаем с Mono. Часть 1

Основные принципы Mono, инструменты, создание простейшего приложения

Comments

Серия контента:

Этот контент является частью # из серии # статей: Работаем с Mono. Часть 1

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Работаем с Mono. Часть 1

Следите за выходом новых статей этой серии.

Mono — программная платформа, позволяющая разработчикам достаточно просто создавать развитые кроссплатформенные приложения. Технология Mono разрабатывается в виде open source реализации технологии .NET Framework от Microsoft и поддерживает стандарты ECMA-334 (стандарт языка C#) и ECMA-335 (стандарт среды исполнения (Common Language Runtime, CLI). Открытость указанных стандартов позволяет уменьшить проблемы создания кроссплатформенных приложений.

В базовом варианте Mono состоит из нескольких компонентов:

  • Компилятор языка C# — компилятор с полной поддержкой версий 1.0 и 2.0 языка C#. Кроме того в последних версиях поддерживаются практически все возможности версии C# 3.0, а начиная с версии Mono 2.6 включена поддержка возможностей версии C# 4.0 (пока только как опция, полноценная поддержка заявлена в версии 2.8).
  • Среда исполнения Mono — состоит из среды исполнения (CLI) непосредственно, компилятора среды исполнения (Just-In-Time, JIT), генератора машинного кода (Ahead-Of-Time, AOT), загрузчика сборок, сборщика мусора, подсистемы управления многопоточностью и компонентов поддержки взаимодействия между сборками и COM (или аналогами в Linux, например XCOM).
  • Базовая библиотека классов — набор стандартных классов, совместимых с классами Microsoft .NET Framework.
  • Библиотека классов Mono — набор классов, поддерживающих дополнительные функции для разработки Linux-приложений. Например, классы для поддержки Zip, OpenGL, Cairo, Gtk+.

Совместимость Mono и Microsoft .NET Framework

В текущей версии Mono поддерживаются следующие версии и возможности Microsoft .NET Framework:

  1. поддержка версии .NET 1.1:
    • язык C# 1.0;
    • базовые библиотеки версии 1.1: mscorlib, System, System.Xml;
    • ASP .NET 1.1 (разработка веб-приложений);
    • ADO .NET 1.1 (модель доступа к данным);
    • Winforms/System.Drawing 1.1 (пользовательский интерфейс Microsoft Windows);
    • базовые классы пространств имен System.Management (информация о системе, работа с устройствами) и System.EnterpriseServices (разработка масштабируемых бизнес-приложений, преимущественно на базе COM+ технологии) не поддерживаются в связи с отсутствием близких по идеологии технологий в Linux.
  2. поддержка версии .NET 2.0:
    • язык C# 2.0 (поддержка дженериков (шаблонов, generics);
    • базовые библиотеки версии 2.0: mscorlib, System, System.Xml;
    • ASP .NET 2.0 (кроме WebParts);
    • ADO .NET 2.0;
    • Winforms/System.Drawing 2.0 (не поддерживаются языки с письмом справа налево);
  3. поддержка версий .NET 3.0 и 3.5:
    • C# 3.0;
    • System.Core (базовая библиотека классов);
    • LINQ (Language Integrated Query, интегрированный язык запросов);
    • ASP .NET 3.5;
    • ASP .NET MVC (создание веб-приложений с поддержкой шаблона “модель-представление-поведение”);
    • LINQ to SQL — поддержка большинства (но не полного комплекта) функций;
    • WCF (Windows Communication Foundation) — частичная поддержка на уровне библиотек Silverlight 2.0;
    • WPF (Windows Presentation Foundation) — не поддерживается и пока поддержка не планируется;
    • WF (Workflow Foundation) — не поддерживается, планируется поддержка с версии WF4;
  4. поддержка версии .NET 4.0, реализованная в версии Mono в SVN:
    • C# 4.0;
    • ASP .NET 4.0 (пока частичная поддержка);
    • LINQ 4.0.

Описание основных компонентов и возможностей Mono

Компилятор Mono C# поддерживает версии языков C# 1.0, 2.0 и 3.0. Для создания кода можно использовать один из нескольких вариантов компилятора, в зависимости от потребностей:

  • mcs — компилятор, поддерживающий версию 1.1 среды исполнения. Компилирует код на языках C# 1.0 и C#3.0 (без поддержки дженериков и всего, что с ними связано). Данный компилятор планируется исключить в версии Mono 2.8, как устаревший.
  • gmcs — компилятор, поддерживающий версии от 2.0 до 3.5 среды исполнения и обладающий полной поддержкой C# 3.0.
  • smcs — опциональный компилятор для создания Moonlight (аналог Microsoft Silverlight) приложений.
  • dmcs — опциональный компилятор, реализованный в тестовом варианте в версии Mono 2.6 и планируемый к включению в версию 2.8. Поддерживает среду исполнения версии 4.0 и язык C# 4.0.

Начиная с версии Mono 2.2 реализована поддержка классов компилятора Mono.CSharp.Evaluator (сборка Mono.Sharp.dll) для создания собственных сервисов компиляции.

Среда исполнения Mono поддерживает инфраструктуру промежуточного языка CLI (Common Language Infrastructure), соответствующую стандарту ECMA-335. Виртуальная машина среды исполнения допускает возможность запуска приложений и сборок, скомпилированных в других системах (например, возможно запускать в Linux без перекомпиляции приложения, созданные при помощи Microsoft Visual Studio для исполнения в Microsoft Windows).

Также, вместо использования виртуальной машины, среда исполнения может быть интегрирована в приложение с целью создания встраиваемой системы, не требующей установки Mono для запуска и обладающей высоким быстродействием. При этом, в приложение включаются только необходимые компоненты среды исполнения.

В среде Mono реализован Ahead-Of-Time (AOT) компилятор промежуточного языка. Цель этого компилятора в том, чтобы уменьшить время запуска программы и оптимизировать ее код, путем компиляции промежуточного языка CLI в машинный код. Аналогом в Microsoft .NET Framework является утилита Ngen. Для запуска приложения в этом режиме можно воспользоваться опцией --aot среды исполнения (также можно включить полную оптимизацию кода при помощи опцее -O=all). Например:

mono -O=all –aot program.exe

В качестве сборщика мусора в данный момент используется Boehm's GC, однако в текущей разрабатываемой ветке SVN присутствует совершенно новый сборщик мусора, разработанный специально для Mono.

Установка Mono

Mono входит в репозитории огромного количества дистрибутивов, поэтому проблем с установкой из репозитория возникнуть не должно. Другой вопрос, какие версии располагаются в репозиториях. На данный момент на сайте проекта Mono предлагается скачать бинарные файлы версии 2.4.x. Эти же версии лежат в репозиториях современных дистрибутивов. Последней стабильной версией Mono считается 2.6.3, которая имеется только в виде исходных текстов.

Если есть желание установить Mono 2.6.3, то придется заняться самостоятельной сборкой версии из исходных текстов.

В качестве подопытной системы выберем недавно вышедшую Ubuntu 10.04. Тем не менее пользователям других версий и дистрибутивов это не должно особенно огорчать, потому что разница будет только в менеджерах пакетов и именах пакетов.

Для чистоты эксперимента, чтобы определить все пакеты, которые нужны, возьмем систему Ubuntu 10.04 установленную с нуля и обновленную (при помощи Synaptic или aptitude) до текущего состояния.

Первым делом создадим каталог для исходных текстов и сборки проектов:

mkdir ~/projects/mono
cd ~/projects/mono

Для работы с пространством имен System.Windows.Forms (на классах которого построен графический интерфейс операционных систем семейства Microsoft Windows) необходимо установить библиотеку libgdiplus, которая реализует функции Microsoft GDI+ для Mono. Взять исходные тексты этой библиотеки можно с сайта проекта Mono:

wget http://ftp.novell.com/pub/mono/sources/libgdiplus/libgdiplus-2.6.2.tar.bz2

Распакуем исходные тексты и перейдем в каталог проекта:

tar jxf libgdiplus-2.6.2.tar.bz2
cd libgdiplus-2.6.2

При базовой установке Ubuntu устанавливается минимальный набор инструментов для разработчика, поэтому необходимо проследить, чтобы нужные инструменты присутствовали в системе. Для установки и работы потребуются компилятор g++, парсер Bison, интерпретатор макроязыка M4, библиотека Glib 2.0, GetText для поддержки интернационализации. Для работы с Mono требуется также Pkg-config. При отсутствии в системе эти пакеты (и их зависимости) нужно будет установить. Для Ubuntu это делается командой:

sudo apt-get install libglib2.0-dev m4 bison gettext pkg-config

Для работы библиотеки libgdiplus нужна библиотека libcairo2 версии не ниже 1.6.4. Эта библиотека входит в состав исходных текстов libgdiplus и может быть скомпилирована совместно с ней, однако при наличии более свежей версии рекомендуется пользоваться именно ей. В репозиториях Ubuntu 10.04 лежит libcairo2 версии 1.8.10. Установим ее из репозитория:

sudo apt-get install libcairo2-dev

Остается только сконфигурировать и собрать libgdiplus. По умолчанию установка производится в каталог /usr/local/bin для библиотеки и /usr/local/include для заголовочных файлов, что не всегда удобно, так как в будущем понадобится настройка переменных окружения LD_LIBRARY_PATH и LD_RUN_PATH. Удобнее, если библиотеки и заголовочные файлы будут расположены в /usr/bin и /usr/include соответственно.

./configure –prefix=/usr
make
sudo make install

Скачиваем mono runtime:

cd ..
wget http://ftp.novell.com/pub/mono/sources/mono/mono-2.6.3.tar.bz2
cd mono-2.6.3

Рассмотрим наиболее интересные параметры конфигурации исходных текстов:

--with-xen-opt=yes,no

Этот параметр установлен в yes по умолчанию. При этом mono оптимизмруется для работы под средствами виртуализации Xen. В реальной среде производительность несколько ниже. Мы в нашем случае будем использовать no.

--with-large-heap=yes,no

Возможность выделения приложением больших объемов памяти (свыше 3 Гб). По умолчанию no.

--with-moonlight=yes,no

Включение поддержки Moonlight — свободного аналога Microsoft Silverlight.

--with-libgdiplus=installed,sibling,<path>

Местоположение библиотеки libgdiplus для поддержки классов System.Windows.Forms. Значение installed означает, что библиотека установлена в системе (как в нашем случае), sibling — исходные тексты библиотеки лежат в каталоге с текстами mono, <path> — библиотека установлена по указанному пути (используется, если библиотека установлена в нестандартный каталог или установлено несколько разных версий в разных каталогах).

--enable-big-arrays

Включение поддержки больших массивов, у которых индекс выходит за пределы Int32.MaxValue. По умолчанию такие массивы не поддерживаются даже в 64-битных системах (в том числе и в Microsoft Windows для архитектуры x64).

--enable-parallel-mark

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

Конфигурируем и устанавливаем Mono:

./configure –prefix=/usr –with-xen-opt=no –with-moonlight –with-libgdiplus=installed
make
sudo make install

В моем случае изначально сборка закончилась неудачно в связи с тем, что make почему-то не хватило прав, хотя собиралось все в домашнем каталоге пользователя. Если вдруг такое произошло, помогает sudo make вместо make.

Mono Runtime готов к работе.

Создание первого приложения

С целью протестировать работоспособность Mono создадим традиционное приложение Hello World с выводом в терминал и вариант с созданием окна.

Для вывода в терминал воспользуемся методом WriteLine класса Console.

cd ~/projects
cat > hello_world1.cs << “EOF”
using System;
public class HelloWorld
{
static public void Main()
{
Console.WriteLine(“Hello World! This is our first Mono program”);
}
}
EOF

Скомпилируем программу с поддержкой .NET версии 1.1:

mcs hello_world1.cs

Или с поддержкой .NET версии 2.0:

gmcs hello_world1.cs

Компиляция должна пройти без ошибок и запуск:

mono hello_world1.exe

приводит к выводу в консоль сообщения “Hello World! This is our first Mono program”

Сделаем ознакомительное приложение с использованием графического интерфейса. В среде Linux уместнее всего было бы использовать библиотеки Gtk#, однако в данный момент эта библиотека не установлена и это будет темой одной из будущих статей. Воспользуемся библиотекой Winforms, которая входит в состав Mono по умолчанию. Работа с этой библиотекой также будет описана в будущих статьях, поэтому код дается без комментариев.

cat > hello_world2.cs << “EOF”
using System;
using System.Windows.Forms;
public class Hello : Form
{
static public void Main()
{
Application.Run(new Hello());
}
public Hello()
{
Text=”Hello World! This is our first Mono program”;
}
}
EOF

Скомпилируем программу с поддержкой .NET версии 1.1:

mcs hello_world2.cs -pkg:dotnet

Или с поддержкой .NET версии 2.0:

gmcs hello_world2.cs -pkg:dotnet

Не забываем указать ключ -pkg:dotnet, подключающий библиотеки, содержащие пространство имен System.Windows.Forms.

После запуска:

mono hello_world2.exe

на экране появится пустое окно с заголовком “Hello World! This is our first Mono program” и кнопками сворачивания, разворачивания и закрытия.

MoMA — анализатор “чужих” сборок

Как было сказано выше, Mono совместим с .NET Framework на уровне исполняемых файлов и сборок. Однако, как это часто бывает, запуск скомпилированных, например, в Microsoft Visual Studio программ заканчивается ошибочно. В этом случае не помешает определить, стало ли причиной ошибки отсутствие какой-либо библиотеки в среде Mono в Linux (и решить проблему установкой этой библиотеки) или проблема связана с тем, что та или иная возможность не поддерживается в Mono.

В этом поможет инструмент Mono Migration Analyzer (MoMA), который можно скачать с сайта проекта Mono.

Для запуска MoMA его нужно распаковать в отдельный каталог и запустить сборку MoMA.exe:

unzip -x moma2-6.zip
cd MoMA
mono MoMA.exe

Тестирование сборок на совместимость состоит из пяти шагов и интуитивно понятно, более того реальный шаг всего один — выбор сборок для тестирования, остальные шаги содержат справочную информацию, итоги тестирования и форму для сбора информации о том, как улучшить данный инструмент.

Следует отметить, что MoMA — инструмен достаточно простой, поэтому возможны варианты, что какие-то проблемы в коде найдены не будут, а также возможно нахождение проблемы, которая, тем не менее, не помешает исполнению кода.

Все проблемы, которые находит MoMA можно свести к четырем видам.

  1. Missing Methods — отсутствующие методы.

    В сборке присутствует вызов методов, которые не имеют никакой реализации (в том числе даже заглушки) в Mono. Если такое приложение попытаться скомпилировать в Mono, это приведет к ошибке вида:

    file1.cs(10,15): error CS0117: 'xxxxx' does not contain a definition for 'yyyyy'

    Если же данный код скомпилировать, например, в Visual Studio, а затем запустить в среде Mono, это приведет к исключению System.MissingMethodException при вызове отсутствующего метода.

    Бороться с этой проблемой можно двумя способами. Первый состоит в том, чтобы заменить отсутствующий метод другими методами, реализующими ту же задачу. Второй состоит в том, чтобы реализовать отсутствующий метод и, по возможности, предложить его для включения в новую версию Mono.

  2. MonoTodo — вызов методов, реализованных частично.

    Вызов подобных методов может привести к проблеме, а может и не привести. Как правило атрибутом [MonoTodo] помечаются методы, в которых либо нереализована какая-то небольшая часть функциональности, либо метод нуждается в чистке и оптимизации. При использовании данных методов проблем, скорей всего не будет, хотя часть функциональности может оказаться недоступной.

    Если проблема возникает, можно обойти использование данного метода, дождаться его более полной реализации в будущих версиях Mono или реализовать самостоятельно и включить в будущие версии.

  3. NotImplementedException — исключение “метод не реализован”.

    Проблема очень похожа на предыдущую с той разницей, что при каких-то обстоятельствах метод может вернуть исключение NotImplementedException. Проявится проблема или нет можно понять только после тестирования приложения в среде Mono. Если проблема проявляется, то пути для ее решения будут такими же, как и в предыдущем случае.

  4. P/Invokes (Platform Invokes) — вызов функций, написанных на неуправляемых языках.

    Проблема может возникнуть, если, например, используется вызов методов COM-объектов в среде Microsoft Windows. Само собой разумеется, что эти объекты не имеют реализации в Linux. Решить проблему можно реализовав схожую функциональность в управляемом коде или создав необходимую библиотеку для Linux.

    Если же вызов происходит из COM-объектов, написанных самостоятельно, то должна быть обеспечена их кроссплатформенность, тогда ошибок при исполнении кода не будет. В противном случае лучше изменить реализацию так, чтобы вызовы из COM-объектов не использовались.

Работа с MoMA из командной строки

В случае, если использование графического интерфейса не нужно или невозможно, можно использовать MoMA из командной строки.

При этом указывается параметр --nogui, может быть указан параметр --out с указанием месторасположения отчета об анализе, а затем указывается одна или несколько анализируемых сборок. Например:

mono MoMA.exe --nogui --out Report.html App.exe ../Lib1.dll ../Lib2.dll Lib3.dll

Заключение

Мы рассмотрели основные возможности среды исполнения Mono. К сожалению, большинство подробностей о внутренней работе среды исполнения и библиотеках (в том числе и более подробное рассмотрение кода простых приложений этой статьи) остались не охваченными, однако многие из пробелов будут рассмотрены в будущих статьях. Кроме того, большая часть информации о функционировании .NET Framework актуальна и для Mono. Так, например, рекомендуется ознакомиться с обзором .NET Framework.


Ресурсы для скачивания


Похожие темы


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Linux
ArticleID=590198
ArticleTitle=Работаем с Mono. Часть 1: Основные принципы Mono, инструменты, создание простейшего приложения
publish-date=11232010