這是一個老問題(與已實施的各類web應用程序選定的答案),但我不相信這個問題真的回答得很好。
首先,有點背景...
如何.NET工作?
傳統的Windows .EXE文件是一個二進制文件,代表您的計算機可以理解的一系列機器語言指令,並且可以調用Win32 API,這些API是Windows的一部分,可以提供應用程序可以利用的服務。所使用的機器語言對於您的計算機類型非常具體,而Win32調用使可執行文件非常依賴於Windows。 .NET可執行文件不是這樣的。
認識到.NET可執行文件(.EXE文件)實際上並不是本機Windows應用程序很重要。 Windows本身並不瞭解如何在.NET可執行文件中運行代碼。你的電腦也不理解它。
與Java非常相似,.NET應用程序由一種稱爲CIL(通用中間語言)的語言組成,您可以將它視爲理想化計算機的機器語言,但實際上並不存在。在.NET中,這種理想化機器的軟件實現被稱爲公共語言運行時(CLR)。 Java世界中的等價物稱爲Java虛擬機(JVM)。在Java中,與CIL等價的稱爲Java字節碼。 CIL有時被稱爲MSIL(Microsoft中間語言)。
CIL旨在運行在CLR(理想化的機器)上,但是在其他方面與平臺無關,這意味着CIL不關心您擁有哪種計算機或正在運行的操作系統。
正如你所需要的Java的JVM的要在其上運行的Java每個平臺上本地版本,你需要的CLR的原生版本運行.NET CIL可執行文件。 CLR是一個本地Windows應用程序,就像上面介紹的傳統Win32 EXE文件一樣。 CLR本身特定於其設計運行的Windows實現和計算機體系結構。 (C#,VisualBasic,F#,IronPython,IronRuby,Boo等),它們都被編譯爲CIL字節碼,這並不重要。您可以輕鬆地將CIL程序「反彙編」爲易於人類閱讀的面向對象的彙編語言形式。你可以直接在CIL編寫一個程序,但很少有人這樣做。
在Windows上,CLR編譯此CIL代碼只是在實時(JIT),權當您運行可執行程序 - 代碼實際運行之前。這意味着CIL字節碼將被轉換(編譯)爲在您的計算機上本機運行的實際機器代碼。這部分CLR被稱爲JIT編譯器或通常只是JIT。
迄今爲止,微軟已經發布了四個版本的CLR:1.0,1.1,2.0和4.0。如果要運行面向該運行時的.NET可執行文件,則需要在計算機上安裝正確版本的CLR。 CLR 2.0支持.NET 2.0,3.0和3.5應用程序。對於其他版本的.NET,.NET版本完全映射到CLR版本。
除了JIT/CLR,.NET提供了組成.NET框架的其餘部分,提供的是.NET應用程序時可以調用功能和服務的主機庫(組件)的主機。絕大多數這些程序集都是在CLR上運行的純CIL代碼。在Windows上,一些人也會調用Win32 API。當您安裝.NET時,您正在安裝CLR,類庫(框架)以及一些開發工具。每個版本的CLR通常都需要一套完整的「框架」程序集。某些版本的.NET(例如3.0和3.5)添加了額外的框架程序集,而無需更新CLR或與該CLR相關聯的現有程序集。
,一個視窗.EXE文件被遞送的可移植可執行(PE)文件格式包含描述可執行文件和文件標識爲一個.NET文件或天然Win32文件的報頭。當Windows試圖運行一個.NET文件時,它會看到這個頭文件並自動以您的名義調用CLR。這就是爲什麼.NET EXE文件似乎在Windows上本地運行的原因。
好吧,莫諾如何工作?
單實現在Linux,Mac和其他平臺的CLR。 Mono運行時(CLR)是一種原生應用程序,主要用C語言編寫,並編譯爲設計運行的計算機系統的機器語言代碼。與Windows一樣,Mono運行時特定於您正在使用的操作系統和機器種類。
就像在Windows上運行單(在CLR)編譯CIL字節碼在.NET可執行剛剛在時間爲本地代碼,您的計算機能夠理解並執行。通過這種方式,.NET文件對於Linux來說與Windows一樣「原生」。
要將Mono移植到新架構,您需要移植JIT/CLR。這就像將任何本機應用程序移植到新平臺一樣。
.NET代碼在Linux或Mac上運行的程度如何,實際上只是CLR在這些系統上的實現情況。理論上,Mono CLR可以在這些系統上執行.NET代碼,比在Windows上運行的MS版本要好得多。實際上,MS的實施通常比較好(儘管不是所有情況)。
除了CLR,Mono提供最組成.NET框架庫(組件)的其餘部分。就像Microsoft的.NET版本(實際上更多)一樣,Mono程序集也是以CIL字節碼的形式提供的。這使得從Mono獲取* .dll或* .exe文件成爲可能,並且在Windows,Mac或Linux上不加修改地運行它,因爲CIL是這些系統上CLR實現的「本地」語言。
就像在Windows上,單聲道支持CLR的多個版本以及相關的組件:
單的
極早期版本(1.2之前?)只支持CLR 1.0或1.1。 Mono直到它自己的2.0版本才支持2.0框架的大塊。
版本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不再支持。
單2.10繼續使用CLR 4.0爲默認,也支持CLR 2.0。
就像真正的.NET(但少得多的情況下),還有一些調用本機庫的一些單集。爲了使System.Drawing程序集在Mono上工作,Mono團隊編寫了一個Linux程序來模擬Linux上Win32 API的GDI +部分。這個庫被稱爲'libgdiplus'。如果你從源代碼編譯Mono,你會注意到在構建'mono'之前你需要建立這個'libgdiplus'文件。 Windows上不需要'libgdiplus',因爲Win32 API的GDI +部分已經是Windows的一部分。全新的Mono端口需要這個'libgdiplus'庫才能移植。
在所在區域的.NET庫的設計過於由Windows的設計,一個貧窮適合喜歡Mac或Linux系統的影響,Mono團隊編寫的擴展到.NET框架。單聲道擴展也只是CIL字節碼,通常在.NET上工作得很好。
與Windows不同,Linux通常不檢測.NET可執行文件並默認啓動CLR。用戶通常必須通過輸入'mono appname.exe'或類似的東西來直接運行CLR。這裏'mono'是實現CLR的應用程序,'appname.exe'是包含要執行的.NET代碼的EXE文件。
爲了讓事情更容易爲用戶,單應用程序通常包裹在啓動CLR的shell腳本。這就隱藏了CLR正在像Windows一樣被使用的事實。當遇到使用PE文件格式的文件時,也可以告訴Linux啓動CLR。這通常不會完成,因爲PE文件格式也用於本機Win32 Windows可執行文件,這當然是CLR(Mono)不支持的。
沒有技術上的原因,爲什麼一個PE啓動程序不能被Linux使用,然後啓動一個理解原生Windows代碼(如Wine)或CLR(Mono)的系統。這根本不是我所知。
來回
是堅持「全託管」的代碼,這意味着它不會調用到non-.NET碼,應在所有平臺上單做工精細任何.NET代碼。我經常在Linux和Mac上使用Windows編譯的.NET程序集(對此我沒有代碼)。
我也可以使用任何我在Mono上編譯並在Windows上運行.NET的代碼。我可以向客戶端提供一些我用Mono編譯的代碼,而不用擔心他是否在32位或64位Windows上。客戶端確實需要安裝正確版本的.NET(正確的CLR)。 CLR 2.0已經存在很長時間了,你可以打賭幾乎所有的Windows用戶都安裝了它。單聲道編譯器和其他代碼也只是CIL可執行文件,所以如果你願意,它們可以在Windows上正常運行。
單聲道兼容性足夠好,可以從實際的MS版本的.NET中獲取大量實際Microsoft代碼(如ASP.NET MVC)(在合法的情況下),並在Mac或Linux上運行。一般來說,Mono團隊在實現CLR和框架的其他部分(類庫/程序集)方面做得很好。
ASP.NET
在Windows,Internet信息服務器(IIS)知道如何調入CLR執行.NET的Web應用程序的一部分。在Linux/Mac上有一個Apache模塊(mod_mono),它提供了與Apache網絡服務器類似的功能。此應用程序是用C語言編寫的,也必須移植到新架構。
移植單
這個討論已經確定了被構建爲「原生」的可執行文件和必須存在於要運行的.NET應用程序的系統上單的部分。
- 的CLR(包括JIT編譯器) - 通常被稱爲單聲道
- libgdiplus(爲其本身不支持的GDI + API系統[僅Windows並])
- 是mod_mono(以允許Apache的調用CLR for .NET Web應用程序)
這三個組件提供了一個.NET環境,該環境對於需要運行的.NET可執行文件來說是「本機」的。
這就是莫諾的工作原理。
任何機會稍微更詳細的版本? :) – DavidG 2008-10-19 19:46:04
我擔心我對deep depp細節的理解不夠好(我大致知道PE標題是什麼,但不是真正的細節),但是我發現這些鏈接很有用:http://is.gd/ 4n4i http://is.gd/4n4n – 2008-10-19 19:53:26
EXE內部沒有「真正的」Windows本機部分。標題只是一個描述。它可能指向EXE或DLL中的入口點,但這可以由主機環境執行或不執行。實際的「啓動程序」是可執行程序的外部,並且可以是Windows本機或CLR的一部分(對於.NET和Mono)。 – Justin 2011-03-04 01:26:56