我在Visual Studio with .NET中使用过C#,我在openSUSE Linux上玩过Mono,但我真的不明白它是如何工作的。

如果我在.NET上使用Windows编写应用程序,这与Mono有什么关系?我不能在没有Wine的情况下在Linux上执行Windows .exe文件,因此它无法帮助我执行在Windows中开发的应用程序。

目的是纯粹在Linux(和其他)上使用.NET库等同于使跨平台开发更容易吗?例如,如果我是一家企业并且想要接触Linux客户,但是真的想使用.NET,那么Mono应该是我的选择吗?还是有更多我想念的东西?

有帮助吗?

解决方案

Windows EXE包含多个“部分”。 简化,.net代码(= MSIL)只是EXE的一部分,并且还有一个“真实”部分。 EXE中的本机Windows部分,作为.net Framework的某种启动程序,然后执行MSIL。

Mono将只接受MSIL并执行它,忽略本机Windows Launcher的东西。

同样,这是一个简化的概述。

编辑:我担心我对深层细节的理解对于非常详细的细节来说还不够(我大致知道什么是PE标题,但不是真正的细节),但我发现这些链接有用:

NET Assembly Structure–第二部分

.NET基础 - .NET程序集结构

其他提示

这是一个老问题(已经选择了答案),但我不相信这个问题确实得到了很好的回答。

首先,一点背景......

.NET如何运作?

传统的Windows .EXE文件是一个二进制文件,它表示计算机可以理解的一系列机器语言指令,并调用Win32 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的每个平台上使用Java JVM的本机版本一样,您需要CLR的本机版本才能运行.NET CIL可执行文件。 CLR是一个本机Windows应用程序,就像上面描述的传统Win32 EXE文件一样。 CLR本身特定于Windows实现和计算机体系结构的运行。

你开始使用什么.NET语言(C#,VisualBasic,F#,IronPython,IronRuby,Boo等)并不重要,它们都被编译成CIL字节码。你可以轻松地“反汇编”将CIL程序转换为面向对象的汇编语言形式,人类可以轻松阅读。您可以直接在CIL中编写程序,但很少有人这样做。

在Windows上,CLR在运行可执行文件时正确编译此CIL代码实时(JIT) - 就在代码实际运行之前。这意味着CIL字节码被转换(编译)为在您的计算机上本机运行的实际机器代码。 CLR的这一部分称为JIT编译器,或者通常只称为JIT。

到目前为止,Microsoft已发布了四个版本的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关联的现有程序集。

提供Windows .EXE文件的可移植可执行文件(PE)文件格式d in包含描述可执行文件的标头,并将文件标识为.NET文件或本机Win32文件。当Windows尝试运行.NET文件时,它会看到此标头并代表您自动调用CLR。这就是.NET EXE文件似乎在Windows上本机运行的原因。

好的,那么Mono如何运作?

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

就像在Windows上一样,Mono运行时(CLR)将.NET可执行文件中的CIL字节码及时编译为计算机可以理解和执行的本机代码。通过这种方式,.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上一样,Mono支持多个版本的CLR和相关的程序集:

Mono的早期版本(1.2之前?)仅支持CLR 1.0或1.1。 Mono不支持2.0框架的大块,直到它自己的2.0版本。

2.4版本的Mono版本支持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程序来模拟Linux上Win32 API的GDI +部分。这个库叫做'libgdiplus'。如果你从源代码编译Mono,你会发现你需要构建这个'libgdiplus'文件才能构建'mono'。您在Windows上不需要“libgdiplus”,因为Win32 API的GDI +部分已经是Windows的一部分。 Mono到新平台的完整端口也需要移植这个'libgdiplus'库。

在.NET库的设计受到Windows设计的过度影响以及不适合Mac或Linux等系统的领域,Mono团队已经编写了.NET框架的扩展。 Mono扩展也只是CIL字节码,通常在.NET上运行良好。

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

为了让用户更轻松,Mono应用程序通常包含在启动CLR的shell脚本中。这隐藏了fa

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

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

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

但是正如提到Mono是开源的,你不能仅仅依赖它将是完整的.NET实现,它有一些不起作用的控件,你必须小心P / Invokes你的应用程序将使用,例如您的应用程序将与win32下的MCI(多媒体控制器接口)通信。但我也使用单声道写GTK#应用程序,但我也使用了我的Windows应用程序,无需重新编译,如上面提到的我们的程序员,也就是说,mono是Microsoft的.NET的开源替代品,默认情况下,如果你正在构建WinForms或Gtk#应用程序mono将编译并将为每个文件创建一个.exe程序集,当然如果你想要它将创建一个动态链接库(DLL),几乎就像在.NET中一样。只是为了建议尝试编写一些Gtk#(使用MonoDevelop IDE,其内置的gui设计师称为stetic)。当然,mono可以很好地替代你可以在.NET上创建它们的Web服务,你可以在Apache上托管它们(因为现在Linux托管比Windows更便宜)web服务和其他asp.net应用程序可以在带有mod_mono模块的apache,必须包含在apache中。

有点偏离主题,但我只想告诉你我的经验。

此外,您可以查看MoMA(如果您的目标是将应用程序从Win移植到Lin)。

  

单声道迁移分析仪(MoMA)   工具可帮助您识别可能出现的问题   移植你的.Net时有   应用于Mono。它有助于精确定位   特定于平台的调用(P / Invoke)和   尚未支持的区域   Mono项目。

MoMA

这是一个webapp,用于比较Mono和.NET Framework 3.5已经实现的BCL类型

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

为了进一步迈克尔的回应,我相信你将不得不重新编译Mono,让应用程序在Mono运行时运行。可能存在例外情况。我只和Mono玩了一下,我总是重新编译源代码。我从未试图直接在Mono上运行.NET应用程序。

此外,Mono 1.9应该完全符合.NET 2.0标准。 Mono Olive和Moonlight应该添加.NET 3.0(更少的WPF)和Silverlight功能。

它可能会对您有所帮助, Mono的C#编译器如何工作?以及了解Mono C#编译器书。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top