Jest to stary pytanie (z już wybraną odpowiedź), ale nie sądzę, aby na to pytanie dobrze odpowiedziano.
Po pierwsze, trochę w tle ...
Jak działa .NET?
Tradycyjny plik .EXE systemu Windows jest plikiem binarnym, który reprezentuje serię instrukcji języka maszynowego, które komputer rozumie i nawiązuje połączenia z interfejsem Win32 API, które są częściami systemu Windows oferującymi usługi, z których mogą korzystać aplikacje. Użyty język komputera jest bardzo specyficzny dla twojego komputera, a wywołania Win32 sprawiają, że plik wykonywalny jest bardzo zależny od systemu Windows. Plik wykonywalny .NET nie jest taki.
Należy pamiętać, że plik wykonywalny .NET (plik EXE) w rzeczywistości nie jest natywną aplikacją systemu Windows. Sam system Windows nie wie, jak uruchomić kod w pliku wykonywalnym .NET. Twój komputer też tego nie rozumie.
Podobnie jak Java, aplikacja .NET składa się z instrukcji w języku zwanym CIL (Common Intermediate Language), który można uznać za język maszynowy dla wyidealizowanego komputera, który tak naprawdę nie istnieje. W .NET implementacja tego wyidealizowanego komputera nosi nazwę Common Language Runtime (CLR). Odpowiednik w świecie Java nazywa się wirtualną maszyną Java (JVM). W Javie odpowiednik CIL nazywa się bajtowym kodem Java. CIL jest czasem nazywany MSIL (Microsoft Intermediate Language).
CIL jest przeznaczony do pracy na CLR (wyidealizowana maszyna), ale jest poza tym niezależny od platformy, co oznacza, że CIL nie dba o to, jaki masz komputer lub jaki system operacyjny używasz.
Tak jak potrzebujesz natywnej wersji Java JVM na każdej platformie, na której chcesz uruchomić Javę, potrzebujesz natywnej wersji środowiska CLR do uruchamiania plików wykonywalnych .NET CIL. CLR jest natywną aplikacją Windows, podobnie jak tradycyjne pliki Win32 EXE opisane powyżej. Sam CLR jest specyficzny dla implementacji Windows i architektury komputerowej, dla której został zaprojektowany.
Nie ma znaczenia, z jakiego języka .NET zaczniesz (C#, VisualBasic, F #, IronPython, IronRuby, Boo itd.), Wszystkie zostaną skompilowane do kodu bajtowego CIL. Możesz łatwo "zdemontować" program CIL w postaci obiektowego języka asemblerowego, który jest łatwy do odczytania przez ludzi. Możesz napisać program bezpośrednio w CIL, ale niewiele osób to robi.
W systemie Windows CLR kompiluje ten kod CIL "Just-in-Time" (JIT) tuż po uruchomieniu pliku wykonywalnego - tuż przed faktycznym uruchomieniem kodu. Oznacza to, że kod bajtowy CIL jest konwertowany (kompilowany) na rzeczywisty kod maszynowy, który działa natywnie na twoim komputerze. Ta część CLR jest nazywana kompilatorem JIT lub często tylko JIT.
Do tej pory firma Microsoft wydała cztery wersje środowiska CLR: 1.0, 1.1, 2.0 i 4.0. Aby móc uruchamiać pliki wykonywalne .NET kierowane na to środowisko, na komputerze musi być zainstalowana odpowiednia wersja środowiska CLR. CLR 2.0 obsługuje aplikacje .NET 2.0, 3.0 i 3.5. W przypadku innych wersji .NET wersja .NET jest mapowana czysto do wersji CLR.
Oprócz JIT/CLR. NET dostarcza wiele bibliotek (złożeń), które składają się na resztę architektury .NET i zapewniają wiele możliwości i usług, z których mogą korzystać aplikacje .NET. Ogromna większość tych zespołów to czysty kod CIL, który działa na CLR. W systemie Windows niektóre wywołują również wywołania Win32 API. Podczas instalacji .NET instalujesz CLR, biblioteki klas (framework) i kilka narzędzi programistycznych. Każda wersja CLR zazwyczaj wymaga kompletnego zestawu tych "szkieletowych" zespołów. Niektóre wersje .NET (np. 3.0 i 3.5) dodawały dodatkowe zespoły szkieletowe bez aktualizacji CLR lub istniejących złożeń powiązanych z tym CLR.
Format pliku Portable Executable (PE), do którego dostarczono plik .EXE systemu Windows zawiera nagłówek opisujący plik wykonywalny i identyfikujący plik jako plik .NET lub macierzysty plik Win32. Kiedy system Windows próbuje uruchomić plik .NET, widzi ten nagłówek i automatycznie wywołuje CLR w twoim imieniu. Właśnie dlatego pliki .NET EXE wydają się działać natywnie w systemie Windows.
Ok, więc jak działa Mono?
Mono implementuje CLR na systemach Linux, Mac i innych platformach. Środowisko wykonawcze Mono (CLR) to natywna aplikacja napisana głównie w języku C i skompilowana do kodu języka komputera dla systemu komputerowego, na którym ma działać. Podobnie jak w systemie Windows, środowisko wykonawcze Mono jest specyficzne dla systemu operacyjnego i rodzaju używanego komputera.
Podobnie jak w Windows, środowisko wykonawcze Mono (CLR) kompiluje kod bajtowy CIL w pliku wykonywalnym .NET Just-in-time na natywny kod, który komputer może zrozumieć i wykonać. W ten sposób plik .NET jest tak samo "natywny" jak dla systemu Linux.
Aby przesłać Mono do nowej architektury, należy przesłać JIT/CLR. Jest to podobne do przenoszenia dowolnej natywnej aplikacji na nową platformę.
Dobrze działający kod .NET na Linuksie lub Macu to tylko kwestia, jak dobrze CLR jest zaimplementowany w tych systemach. Teoretycznie, Mono CLR mógłby wykonywać kod .NET na tych systemach znacznie lepiej niż wersja MS .NETa działająca w systemie Windows. W praktyce wdrożenie MS jest ogólnie lepsze (choć nie we wszystkich przypadkach).
Oprócz CLR, Mono zapewnia większość pozostałych bibliotek (złożeń), które tworzą strukturę .NET. Podobnie jak w wersji Microsoft .NET (w rzeczywistości bardziej), zespoły monofoniczne są dostarczane jako kod bajtowy CIL. Dzięki temu można pobrać plik * .dll lub * .exe z Mono i uruchomić go niezmodyfikowany w systemach Windows, Mac i Linux, ponieważ CIL to "rodzimy" język implementacji CLR w tych systemach.
Podobnie jak w systemie Windows, Mono obsługuje wiele wersji CLR oraz związane z nimi zespoły:
Bardzo wczesne wersje mono (przed 1.2?) Tylko obsługiwane CLR 1.0 lub 1.1. Mono nie obsługiwał dużych fragmentów struktury 2.0, dopóki nie jest własną wersją 2.0.
Wersje mono do wersji 2.4 obsługują zarówno aplikacje CLR 1.1, jak i CLR 2.0.
Począwszy od Mono 2.6, dodano CLR 4.0, ale CLR 2.0 był nadal domyślny.
Począwszy od wersji Mono 2.8, CLR 4.0 stał się domyślny, a CLR 1.1 nie jest już obsługiwany.
Mono 2.10 nadal używa CLR 4.0 jako domyślnego, a także do obsługi CLR 2.0.
Podobnie jak w rzeczywistym .NET (ale w znacznie mniejszej liczbie przypadków) istnieją pewne zespoły monofoniczne, które wywołują biblioteki natywne. Aby zmontować zestaw System.Drawing w Mono, zespół Mono napisał program Linux, aby zasymulować porcję GDI + Win32 API w systemie Linux. Ta biblioteka nazywa się "libgdiplus". Jeśli skompilujesz Mono ze źródła, zauważysz, że musisz zbudować ten plik 'libgdiplus', zanim będziesz mógł zbudować 'mono'. Nie potrzebujesz "libgdiplus" w systemie Windows, ponieważ część interfejsu Win32 API systemu GDI + jest już częścią systemu Windows. Pełny port Mono na nowe platformy wymaga również przeniesienia biblioteki "libgdiplus".
W obszarach, w których konstrukcja biblioteki .NET jest nadmiernie uzależniona od projektu systemu Windows i słabo pasuje do systemów takich jak Mac lub Linux, zespół Mono napisał rozszerzenia do platformy .NET. Rozszerzenia Mono to także kod bajtowy CIL i ogólnie działają dobrze na platformie .NET.
W przeciwieństwie do systemu Windows, Linux zazwyczaj nie wykrywa plików wykonywalnych .NET i domyślnie uruchamia CLR. Użytkownik zwykle musi uruchamiać CLR bezpośrednio, wpisując "mono appname.exe" lub coś podobnego. Tutaj "mono" jest aplikacją, która implementuje CLR, a "appname.exe" jest plikiem EXE, który zawiera kod .NET do wykonania.
Aby ułatwić pracę użytkownikom, aplikacje Mono są często pakowane w skrypt powłoki, który uruchamia środowisko CLR. To ukrywa fakt, że CLR jest używany tak, jak w Windows. Możliwe jest również poinformowanie Linuxa o uruchomieniu CLR, gdy napotkany zostanie plik z formatem pliku PE. Zwykle nie jest to wykonywane, ponieważ format pliku PE jest również używany w przypadku rodzimych plików wykonywalnych systemu Win32, które oczywiście nie obsługują CLR (Mono).
Nie ma żadnego technicznego powodu, dla którego program uruchamiający PE nie mógłby być używany przez system Linux, który uruchamia system rozpoznający natywny kod systemu Windows (np. Wine) lub CLR (Mono). Po prostu nie zostało to zrobione według mojej wiedzy.
iz powrotem
Każdy kod .NET, które przykleja się do „w pełni zarządzane” kod, co oznacza, że nie nazywa się kodem non-.NET, powinien działać dobrze na Mono na wszystkich platformach. Rutynowo używam skompilowanych zestawów .NET z Windows (dla których nie mam kodu) w systemach Linux i Mac.
Mogę również pobrać dowolny kod, który kompiluję w Mono i uruchomić go na platformie .NET w systemie Windows. Mogę dostarczyć klientowi kod skompilowany z Mono i nie martwić się, jeśli jest na przykład w 32-bitowym lub 64-bitowym systemie Windows. Klient musi mieć zainstalowaną odpowiednią wersję .NET (prawy CLR). CLR 2.0 istnieje od bardzo dawna i można założyć, że prawie wszyscy użytkownicy Windows mają go zainstalowanych. Kompilatory Mono i inny kod to także pliki wykonywalne CIL, więc jeśli chcesz, działają poprawnie w systemie Windows.
Kompatybilność w trybie mono wystarcza, aby duże fragmenty rzeczywistego kodu Microsoft, np. ASP.NET MVC, mogły zostać pobrane (jeśli jest to zgodne z prawem) z rzeczywistej wersji MS .NET i uruchomione na komputerach Mac lub Linux. Ogólnie rzecz biorąc, zespół Mono wykonał świetną robotę implementując zarówno CLR, jak i reszta frameworka (biblioteki klas/zespoły).
ASP.NET
W systemie Windows Internet Information Server (IIS) wie, jak zadzwonić do CLR .NET do wykonania w ramach aplikacji internetowej. W systemie Linux/Mac dostępny jest moduł Apache (mod_mono), który zapewnia podobne możliwości do serwera WWW Apache. Ta aplikacja jest napisana w języku C i musi być również przeniesiona do nowych architektur.
Porting Mono
Ta dyskusja zidentyfikował części Mono, które zostały zbudowane jako „native” wykonywalnych i musi istnieć w systemie, na którym chcesz uruchomić aplikacji .NET.
- CLR (w tym JIT kompilator) - powszechnie znany jako Mono
- libgdiplus (dla systemów, które nie natywnie obsługują GDI + API [tylko Windows ma])
- mod_mono (aby umożliwić Apache podniesienia zarzutu CLR dla aplikacji internetowych .NET)
Te trzy komponenty, z dodatkiem bibliotek klas, udostępniają środowisko .NET, które wygląda "natywnie" do plików wykonywalnych .NET, które należy uruchomić.
Tak działa Mono.
masz szansę na nieco bardziej szczegółową wersję? :) – DavidG
Obawiam się, że moje zrozumienie szczegółów głębokiego depp nie jest do tego wystarczające (wiem z grubsza, czym jest nagłówek PE, ale nie tak naprawdę szczegóły), ale uważam, że te linki są pomocne: http://is.gd/ 4n4i http://is.gd/4n4n –
W pliku EXE nie ma "prawdziwej" natywnej części systemu Windows. Nagłówek to tylko opis. Może wskazywać na punkt wejścia w EXE lub DLL, ale jest to albo wykonywalne przez środowisko hosta, albo nie. Rzeczywisty "launcher" jest zewnętrzny do pliku wykonywalnego i jest natywny dla systemu Windows lub część CLR (dla .NET i Mono). – Justin