单声道如何工作

我在Visual Studio中使用了.NET的C#,并且在openSUSE Linux上使用了Mono,但是我不太明白它是如何工作的。

如果我在.NET上编写Windows应用程序,这与Mono有什么关系? 我不能只在Linux上执行没有Wine的Windows .exe文件,所以它不能帮助我执行在Windows中开发的应用程序。

纯粹的目的是在Linux(和其他)上有一个.NET库是否等价,使跨平台开发更容易? 例如,如果我是一个企业,想要联系Linux客户,但是真的想要使用.NET,那么Mono应该是我的select? 还是有更多的东西我失踪?

Windows EXE包含多个“部分”。 .net代码(= MSIL)只是EXE的一部分,在EXE内部还有一个“真正的”本地Windows部分,用作.net框架的某种启动器,然后执行MSIL。

单声道将采取MSIL并执行它,忽略本机Windows启动器的东西。

再次,这是一个简单的概述。

编辑:我担心我对深层细节的理解还不够详细(我大概知道PE标题是什么,但不是真的细节),但是我发现这些链接很有帮助:

NET组装结构 – 第二部分

.NET基础 – .NET组装结构

这是一个老问题(有一个已经选定的答案),但我不认为这个问题真的得到了很好的回答。

首先,有一点背景…

.NET如何工作?

传统的Windows .EXE文件是一个二进制文件,代表您的计算机可以理解的一系列机器语言指令,这些指令可以调用Win32 API,这些API是Windows的一部分,可以提供应用程序可以利用的服务。 使用的机器语言是非常特定于您的计算机types和Win32调用使可执行文件非常依赖于Windows。 一个.NET可执行文件不是这样的。

意识到.NET可执行文件(.EXE文件)实际上不是本机Windows应用程序是非常重要的。 Windows本身不知道如何在.NET可执行文件中运行代码。 你的电脑也不理解它。

就像Java一样,.NET应用程序由一种称为CIL(通用中间语言)的语言组成,您可以将其视为一种理想化的计算机的机器语言,但实际上并不存在。 在.NET中,这个理想化机器的软件实现被称为公共语言运行时(CLR)。 Java世界中的等价物称为Java虚拟机(JVM)。 在Java中,相当于CIL的称为Java字节码。 CIL有时被称为MSIL(Microsoft中间语言)。

CIL被devise为在CLR(理想化的机器)上运行,但是在其他方面与平台无关,这意味着CIL不关心你拥有什么样的计算机或者运行什么操作系统。

正如您需要运行Java的每个平台上的Java JVM的本地版本一样,您需要CLR的本地版本才能运行.NET CIL可执行文件。 CLR是一个本地Windows应用程序,就像上面介绍的传统的Win32 EXE文件一样。 CLR本身特定于Windowsdevise和运行的计算机体系结构。

不pipe你用什么.NET语言(C#,VisualBasic,F#,IronPython,IronRuby,Boo等等),它们都被编译成CIL字节码。 您可以轻松地将CIL程序“拆卸”为一种易于人类阅读的面向对象的汇编语言forms。 你可以直接在CIL编写一个程序,但是很less人做。

在Windows上,CLR在运行可执行文件时正好编译了这个CIL代码Just-in-Time(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应用程序可以调用的大量function和服务。 这些程序集中绝大多数都是在CLR上运行的纯CIL代码。 在Windows上,一些人也调用Win32 API。 当您安装.NET时,您正在安装CLR,类库(框架)以及一些开发工具。 每个版本的CLR通常都需要一套完整的“框架”程序集。 某些版本的.NET(例如3.0和3.5)添加了额外的框架程序集,而无需更新CLR或与该CLR相关联的现有程序集。

提供Windows .EXE文件的可移植可执行文件(PE)文件格式包含一个头文件,该头文件描述了可执行文件并将文件标识为.NET文件或本机Win32文件。 当Windows试图运行一个.NET文件时,它会看到这个头文件并自动以您的名义调用CLR。 这就是为什么.NET EXE文件似乎在Windows上本地运行的原因。

好的,Mono如何工作?

Mono在Linux,Mac和其他平台上实现CLR。 Mono运行时(CLR)是一种原生应用程序,主要以C语言编写,并被编译为devise运行的计算机系统的机器语言代码。 就像在Windows上一样,Mono运行时特定于您正在使用的操作系统和机器种类。

就像在Windows上一样,Mono运行时(CLR)将.NET可执行文件中的CIL字节码编译为您的计算机可以理解和执行的本地代码。 通过这种方式,.NET文件对于Linux来说与Windows一样“原生”。

要将Mono移植到新架构,您需要移植JIT / CLR。 这就像将任何本机应用程序移植到新平台一样。

.NET代码在Linux或Mac上的运行情况如何,实际上只是CLR在这些系统上实现的问题。 从理论上讲,Mono CLR可以在这些系统上执行.NET代码,比在Windows上运行的MS版本要好得多。 在实践中,MS实施通常是优越的(尽pipe不是在所有情况下)。

除了CLR之外,Mono还提供了组成.NET框架的大部分库(组件)的其余部分。 就像Microsoft的.NET版本(实际上更像是),Mono程序集是作为CIL字节码提供的。 这使得从Mono获取* .dll或* .exe文件成为可能,并且在Windows,Mac或Linux上不加修改地运行它,因为CIL是这些系统上CLR实现的“本地”语言。

就像在Windows上一样,Mono支持多种版本的CLR和相关的程序集:

非常早期版本的Mono(1.2之前版本)仅支持CLR 1.0或1.1。 单声道不支持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一样(但是在很less的情况下),有一些Mono程序集调用到本地库中。 为了使System.Drawing程序集在Mono上工作,Mono团队编写了一个Linux程序来模拟Linux上的Win32 API的GDI +部分。 这个库被称为“libgdiplus”。 如果你从源代码编译单声道,你会注意到你需要build立这个'libgdiplus'文件,然后才能build立'单声道'。 您不需要Windows上的“libgdiplus”,因为Win32 API的GDI +部分已经是Windows的一部分。 Mono到新平台的完整端口需要移植这个“libgdiplus”库。

在.NET库的devise过度受到Windowsdevise影响的领域,Mono团队已经写了对.NET框架的扩展,而不适合Mac或Linux系统。 单声道扩展也只是CIL字节码,一般在.NET上工作得很好。

与Windows不同,Linux通常不检测.NET可执行文件,并默认启动CLR。 用户通常必须通过input'mono appname.exe'或类似的东西直接运行CLR。 这里'mono'是实现CLR的应用程序,'appname.exe'是包含要执行的.NET代码的EXE文件。

为了使用户更容易,Mono应用程序通常包含在启动CLR的shell脚本中。 这就隐藏了CLR在Windows中使用的事实。 当遇到使用PE文件格式的文件时,也可以告诉Linux启动CLR。 这通常不会完成,因为PE文件格式也用于本机Win32 Windows可执行文件,CLR(Mono)不支持。

没有技术上的原因,为什么一个PE启动程序不能被Linux使用,然后启动一个理解原生Windows代码(如Wine)或CLR(Mono)的系统。 这根本不是我所知。

来来回回

任何坚持“完全托pipe”代码的.NET代码,这意味着它不会调用非.NET代码,应该在所有平台上的Mono上正常工作。 我经常在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 Information Server(IIS)知道如何调用CLR来将.NET作为Web应用程序的一部分来执行。 在Linux / Mac上有一个Apache模块(mod_mono),它提供了与Apachenetworking服务器类似的function。 此应用程序是用C语言编写的,也必须移植到新的体系结构中。

移植单声道

这个讨论已经确定了构build为“本地”可执行文件的Mono的一部分,并且必须存在于要运行.NET应用程序的系统上。

  • CLR(包括JIT编译器) – 通常称为Mono
  • libgdiplus(对于本身不支持GDI + API的系统[只有Windows有])
  • mod_mono(允许Apache调用.NET Web应用程序的CLR)

这三个组件,增加了类库,提供了一个.NET环境,对于需要运行的.NET可执行文件来说,它看起来是“本地的”。

这就是莫诺的作品。

事实上,您可以在Linux上使用Mono运行.NET .exe文件。 这不需要酒。 实际上,Mono将程序编译为.exe文件,可以在Linux上使用Mono运行,也可以在Windows上运行。

但是正如所提到的那样,Mono是开放源代码的,你不能仅仅依靠它就是完整的.NET实现,它有一些不起作用的控制,你必须谨慎使用你的应用程序将使用的P / Invokes ,例如,您的应用程序将与win32下的MCI(多媒体控制器接口)进行通信。 但是我也使用单声道编写GTK#应用程序,但是我也使用了我的Windows应用程序,没有任何重新编译,正如上面提到的我们的同行程序员,也就是说,mono是Microsoft的.NET的开源替代品,默认情况下,如果您正在构build的WinForms或Gtk#应用程序单声道将编译,并将为每个文件创build一个.exe程序集,当然,如果你想它将创build一个dynamic链接库(DLL),就像它在.NET中完成。 只是build议尝试写一些Gtk#(与MonoDevelop IDE有其内置guidevise师称为stetic)。 当然,单声道可以成为Web服务的一个很好的替代品,你可以在.NET上创build它们,并且你可以在Apache上托pipe它们(因为现在的Linux主机比Windows更便宜),Web服务和其他的asp.net应用程序将工作在apache必须包含在apache中的mod_mono模块。

一点点的话题,但我只是想告诉你,从我的经验偷偷摸摸。

Mono是微软.NET CLR(公共语言运行时)的开源实现。 这是.NET程序的一部分,它不是本地代码,而是CIL(通用中间语言),一种语言和机器中立的中间语言。 运行时采用该中间代码并将其转换为机器代码。

在Mono的当前状态下,您可以使用.NET(mscorlib.dll)的主要部分的.NET程序,并在Mono运行的任何地方运行它们,而不仅仅是Windows。

你也可以看一下MoMA(如果你的目标是将应用程序从Win移植到Lin)。

Mono Migration Analyzer(MoMA)工具可帮助您识别将.Net应用程序移植到Mono时可能遇到的问题。 它有助于查明特定于平台的调用(P / Invoke)以及Mono项目尚不支持的区域。

纽约现代艺术博物馆

下面是一个web应用程序,它比较了Mono和.NET Framework 3.5已经实现的BCL的types

http://mono.ximian.com/class-status/2.0-vs-3.5/index.html

为了进一步迈克尔的回应,我相信你将不得不重新编译单声道的应用程序运行在单声道运行时。 例外可能存在。 我只是玩了一下Mono,而且我一直在重新编译源代码。 我从来没有试图直接在Mono上运行.NET应用程序。

另外,Mono 1.9应该完全符合.NET 2.0。 Mono Olive和Moonlight应该添加.NET 3.0(较lessWPF)和Silverlightfunction。

它可能会帮助你, Mono的C#编译器如何工作? 以及“ 了解Mono C#编译器”一书。