Как работает Mono
Я использовал C# в Visual Studio с.NET и немного поиграл с Mono на openSUSE Linux, но я не совсем понимаю, как это работает.
Если я пишу приложение в Windows на.NET, как это относится к Mono? Я не могу просто выполнить Windows .exe файл в Linux без Wine, поэтому он не помогает мне запускать приложения, разработанные в Windows.
Является ли целью просто иметь эквивалентную библиотеку.NET в Linux (и других), чтобы облегчить кроссплатформенную разработку? Например, если я занимался бизнесом и хотел привлечь клиентов Linux, но действительно хотел использовать.NET, тогда Mono должен быть моим выбором? Или я что-то пропустил?
8 ответов
Windows EXE содержит несколько "частей". Упрощенно,.net-код (=MSIL) - это только часть EXE-файла, а внутри EXE-файла также есть "настоящая" нативная часть Windows, которая служит своего рода средством запуска для.net Framework, которая затем выполняет MSIL.
Mono просто возьмет MSIL и выполнит его, игнорируя нативные средства Windows Launcher.
Опять же, это упрощенный обзор.
Изменить: я боюсь, что мое понимание глубоких глубоких деталей не достаточно хорошо для действительно много деталей (я примерно знаю, что такое PE заголовок, но не совсем детали), но я нашел эти ссылки полезными:
Это старый вопрос (с уже выбранным ответом), но я не верю, что на этот вопрос действительно был получен хороший ответ.
Сначала немного предыстории...
Как работает.NET?
Традиционный Windows-файл.EXE - это двоичный файл, представляющий собой серию инструкций на машинном языке, которые понимает ваш компьютер, и который выполняет вызовы в Win32 API, являющиеся частями Windows, которые предоставляют службы, которыми могут воспользоваться приложения. Используемый машинный язык очень специфичен для вашего типа компьютера, а вызовы Win32 делают исполняемый файл очень зависимым от Windows . Исполняемый файл.NET не такой.
Важно понимать, что исполняемый файл.NET (файл.EXE) на самом деле не является родным приложением Windows . Сама Windows не понимает, как запустить код в исполняемом файле.NET. Ваш компьютер тоже не понимает этого.
Как и Java,.NET-приложение состоит из инструкций на языке CIL (Common Intermediate Language), который можно рассматривать как машинный язык для идеализированного компьютера, которого на самом деле не существует. В.NET программная реализация этой идеализированной машины называется Common Language Runtime (CLR). Эквивалент в мире Java называется виртуальной машиной Java (JVM). В Java эквивалент CIL называется байт-кодом Java. CIL иногда называют MSIL (Microsoft Intermediate Language).
CIL предназначен для работы на CLR (идеализированный компьютер), но в остальном он не зависит от платформы, что означает, что CIL не заботится о том, какой у вас компьютер или какая операционная система у вас установлена.
Точно так же, как вам нужна собственная версия Java JVM на каждой платформе, на которой вы хотите запустить Java, вам также нужна собственная версия CLR для запуска исполняемых файлов.NET CIL. CLR является родным приложением Windows, так же, как традиционные Win32 EXE-файлы, описанные выше. Сам CLR специфичен для реализации Windows и компьютерной архитектуры, на которой он был разработан.
Не имеет значения, с какого языка.NET вы начинаете (C#, VisualBasic, F#, IronPython, IronRuby, Boo и т. Д.), Все они компилируются в байт-код CIL. Вы можете легко "разобрать" программу CIL в форму объектно-ориентированного языка ассемблера, который легко читается человеком. Вы можете сами написать программу на CIL, но мало кто это делает.
В Windows CLR компилирует этот код CIL Just-in-Time (JIT) прямо при запуске исполняемого файла - непосредственно перед тем, как код фактически будет запущен. Это означает, что байт-код CIL преобразуется (компилируется) в фактический машинный код, который изначально выполняется на вашем компьютере. Эта часть CLR называется JIT-компилятором или часто просто JIT.
На сегодняшний день Microsoft выпустила четыре версии CLR: 1.0, 1.1, 2.0 и 4.0. Вам нужно иметь правильную версию CLR, установленную на вашем компьютере, если вы хотите запускать исполняемые файлы.NET, ориентированные на эту среду выполнения. CLR 2.0 поддерживает приложения.NET 2.0, 3.0 и 3.5. Для других версий.NET версия.NET четко отображается на версию CLR.
В дополнение к JIT/CLR.NET предоставляет множество библиотек (сборок), которые составляют остальную часть платформы.NET и которые предоставляют множество возможностей и сервисов, к которым могут обращаться приложения.NET. Подавляющее большинство этих сборок - это чистый CIL-код, который работает на CLR. В Windows некоторые делают вызовы в Win32 API. При установке.NET вы устанавливаете CLR, библиотеки классов (фреймворк) и несколько инструментов разработки. Каждая версия CLR обычно требует полного набора этих "каркасных" сборок. В некоторых версиях.NET (например, 3.0 и 3.5) добавлены дополнительные сборки фреймворка без обновления CLR или существующих сборок, связанных с этим CLR.
Формат файла Portable Executable (PE), в который поставляется файл.EXE Windows, содержит заголовок, который описывает исполняемый файл и определяет файл как файл.NET или собственный файл Win32. Когда Windows пытается запустить файл.NET, она видит этот заголовок и автоматически вызывает CLR от вашего имени. Вот почему.NET EXE-файлы работают в Windows .
Итак, как работает Mono?
Mono реализует CLR на Linux, Mac и других платформах. Среда исполнения Mono (CLR) - это нативное приложение, написанное в основном на языке C и скомпилированное в код машинного языка для компьютерной системы, на которой он предназначен. Как и в Windows, среда выполнения Mono зависит от операционной системы и типа используемой машины.
Как и в Windows, среда выполнения Mono (CLR) компилирует байт-код CIL в исполняемый файл.NET "точно в срок" в собственный код, который ваш компьютер может понять и выполнить. Таким образом, файл.NET так же "родной" для Linux, как и для Windows .
Чтобы перенести Mono на новую архитектуру, вам нужно портировать JIT/CLR. Это похоже на перенос любого нативного приложения на новую платформу.
Насколько хорошо.NET-код работает в Linux или Mac - это вопрос только того, насколько хорошо CLR реализован в этих системах. Теоретически, Mono CLR может выполнять код.NET в этих системах намного лучше, чем MS-версия.NET в Windows . На практике реализация MS, как правило, лучше (хотя и не во всех случаях).
В дополнение к CLR, Mono предоставляет большую часть остальных библиотек (сборок), которые составляют.NET Framework. Как и в версии Microsoft.NET (на самом деле, тем более), сборки Mono предоставляются в виде байт-кода CIL. Это позволяет взять файл *.dll или *.exe из Mono и запустить его без изменений в Windows, Mac или Linux, поскольку CIL является "родным" языком реализации CLR в этих системах.
Как и в Windows, Mono поддерживает несколько версий CLR и связанных с ними сборок:
Очень ранние версии Mono (до 1.2?) Поддерживали только CLR 1.0 или 1.1. Mono не поддерживал большие части фреймворка 2.0, пока не появилась собственная версия 2.0.
Mono версии до версии 2.4 поддерживали приложения CLR 1.1 и CLR 2.0.
Начиная с Mono 2.6, CLR 4.0 был добавлен, но CLR 2.0 по-прежнему оставался по умолчанию.
Начиная с Mono 2.8, CLR 4.0 стал значением по умолчанию, а CLR 1.1 больше не поддерживается.
Mono 2.10 продолжает использовать CLR 4.0 по умолчанию, а также для поддержки CLR 2.0.
Как и в реальном.NET (но в гораздо меньшем числе случаев), есть некоторые сборки Mono, которые обращаются к собственным библиотекам. Чтобы заставить сборку System.Drawing работать на Mono, команда Mono написала программу для Linux, имитирующую часть GDI+ Win32 API на Linux. Эта библиотека называется libgdiplus. Если вы скомпилируете Mono из исходного кода, вы заметите, что вам нужно собрать этот файл 'libgdiplus', прежде чем вы сможете собрать 'mono'. Вам не нужно libgdiplus в Windows, потому что часть WinD API GDI+ уже является частью Windows . Полный порт Mono для новых платформ требует, чтобы эта библиотека 'libgdiplus' также была портирована.
В тех областях, где дизайн библиотеки.NET сильно зависит от дизайна Windows и плохо подходит для таких систем, как Mac или Linux, команда Mono написала расширения для платформы.NET. Расширения Mono также являются просто CIL-байт-кодом и, как правило, прекрасно работают в.NET.
В отличие от Windows, Linux обычно не определяет исполняемые файлы.NET и запускает CLR по умолчанию. Пользователь обычно должен запускать CLR напрямую, набрав "mono appname.exe" или что-то подобное. Здесь "mono" - это приложение, которое реализует CLR, а "appname.exe" - это EXE-файл, содержащий код.NET, который нужно выполнить.
Для облегчения работы пользователей приложения Mono часто заключаются в сценарий оболочки, запускающий CLR. Это скрывает тот факт, что CLR используется так же, как в Windows . Также можно указать Linux запускать CLR при обнаружении файла, использующего формат PE. Обычно этого не делается, поскольку формат файла PE также используется для собственных исполняемых файлов Windows Win32, которые, конечно, CLR (Mono) не поддерживает.
Нет технической причины, по которой средство запуска PE не может быть использовано в Linux, которая затем запускает либо систему, которая понимает собственный код Windows (например, Wine), либо CLR (Mono) в зависимости от ситуации. Это просто не было сделано, насколько мне известно.
Назад и вперед
Любой код.NET, который придерживается "полностью управляемого" кода, что означает, что он не обращается к не-.NET коду, должен нормально работать на Mono на всех платформах. Я обычно использую скомпилированные сборки.NET из Windows (для которых у меня нет кода) на Linux и Mac.
Я также могу взять любой код, скомпилированный в Mono, и запустить его в.NET в Windows . Я могу предоставить клиенту некоторый код, который я скомпилировал с Mono, и не беспокоиться, если он, например, в 32-битной или 64-битной Windows . Клиент должен иметь правильную версию.NET (правильный CLR), установленный для курса. CLR 2.0 существует уже очень давно, и вы можете поспорить, что почти все пользователи Windows установили его. Компиляторы Mono и другой код также являются просто исполняемыми файлами CIL, поэтому они отлично работают в Windows, если хотите.
Моно-совместимость достаточно хороша для того, чтобы большие куски реального кода Microsoft, такие как ASP.NET MVC, можно было взять (где это допустимо) из фактической версии MS.NET для MS и запустить на Mac или Linux. В общем, команда Mono проделала большую работу по реализации как CLR, так и остальной части фреймворка (библиотеки классов / сборки).
ASP.NET
В Windows Internet Information Server (IIS) знает, как вызывать CLR для выполнения.NET как части веб-приложения. В Linux/Mac есть модуль Apache (mod_mono), который предоставляет возможности, аналогичные веб-серверу Apache. Это приложение написано на C и должно быть перенесено на новую архитектуру.
Портирование Моно
В этом обсуждении были определены части Mono, которые созданы как "собственные" исполняемые файлы и должны существовать в системе, в которой вы хотите запускать приложения.NET.
- CLR (включая JIT-компилятор) - обычно известный как Mono
- libgdiplus (для систем, которые изначально не поддерживают API GDI+ [только Windows])
- mod_mono (чтобы позволить Apache вызывать CLR для веб-приложений.NET)
Эти три компонента, с добавлением библиотек классов, обеспечивают среду.NET, которая выглядит "нативно" для исполняемых файлов.NET, которые необходимо запустить.
Вот как работает Mono.
На самом деле вы можете запустить.NET .exe файл с Mono в Linux. Это не требует вина. Фактически, Mono компилирует программы в файлы.exe, которые могут работать с Mono в Linux или как исполняемый файл в Windows.
Mono - это реализация Microsoft.NET CLR с открытым исходным кодом (Common Language Runtime). Это то, что запускает часть программ.NET, которые написаны не на собственном коде, а на CIL (Common Intermediate Language), языке и машинно-нейтральном промежуточном языке. Среда выполнения берет этот промежуточный код и переводит его в машинный код.
В текущем состоянии Mono вы можете брать программы.NET, которые используют основные части.NET (mscorlib.dll), и запускать их везде, где работает Mono, а не только в Windows.
Но поскольку упоминается, что Mono является открытым исходным кодом, и вы не можете просто полагаться, что это будет полная реализация.NET, у него есть некоторые неработающие элементы управления, вы должны быть осторожны с P/Invokes, который будет использовать ваше приложение Например, ваше приложение будет взаимодействовать с MCI (интерфейсом мультимедийного контроллера) под win32. Но я также использовал моно для написания GTK# Applications, но я также использовал свои приложения для Windows, которые работали без перекомпиляции, как уже упоминалось выше, как наши коллеги-программисты, то есть mono - это альтернатива Microsoft.NET с открытым исходным кодом, и по умолчанию, если вы создаете либо WinForms, либо Gtk# приложения. mono скомпилирует и создаст сборку.exe для каждого файла, и, конечно, если вы захотите, то создаст динамическую библиотеку ссылок (DLL), почти так же, как это делается в.NET. Просто для предложения попробуйте написать Gtk# (с MonoDevelop IDE, в которой встроенный графический дизайнер называется stetic). И, конечно же, mono может стать отличной заменой веб-служб, которые вы можете создавать в.NET и размещать в Apache (поскольку хостинг Linux в настоящее время дешевле, чем в Windows), веб-сервисы и другие приложения asp.net будут работать в apache с модулем mod_mono, который должен быть включен в apache.
Немного не в тему, но я просто хотел рассказать вам о моем опыте.
Также вы можете взглянуть на MoMA (если ваша цель - портировать приложения с Win на Lin).
Инструмент Mono Migration Analyzer (MoMA) помогает вам определить проблемы, которые могут возникнуть при переносе приложения.Net в Mono. Это помогает точно определять вызовы для конкретной платформы (P/Invoke) и области, которые еще не поддерживаются проектом Mono.
Вот веб-приложение, в котором сравниваются типы BCL, уже реализованные в Mono и.NET Framework 3.5.
Это может помочь вам, как работает компилятор C# Mono? а также книга " Понимание моно C#".
Чтобы продолжить ответ Михаэля, я думаю, вам придется перекомпилировать Mono, чтобы приложение работало во время выполнения Mono. Исключения могут существовать. Я только немного поиграл с Mono и всегда перекомпилировал исходный код. Я никогда не пытался запустить приложение.NET непосредственно на Mono.
Кроме того, Mono 1.9 должен быть полностью совместимым с.NET 2.0. Mono Olive и Moonlight должны добавить.NET 3.0 (меньше WPF) и функциональность Silverlight.