我对 MSIL 和托管代码感到困惑他们是相同还是不同? 我的意思是说,当我们构建C#代码时会发生什么?
哪一个是对的
C# Code → C# compiler → Managed Code → MSIL
或
C# Code → C# compiler → MSIL
请提供真实的参考或链接以支持您的答案。
答案 0 :(得分:13)
你混淆了不同的东西。 Managed code是用托管语言(C#,VB.NET,F#和许多其他语言)编写的代码,编译成CIL(通用中间语言,以前的Microsoft中间语言或MSIL)并在CLR的托管环境中运行。
另一方面,非托管代码直接编译为本机代码(也称为程序集),它不能在CLR上运行。
当您构建C#代码时,它会被编译为CIL。这就是为什么你可以使用像ildasm或Reflector这样的工具来检查编译的代码。执行CIL代码时到底发生了什么取决于具体情况。它可能是
答案 1 :(得分:10)
如评论中所述,MSIL已更名为CIL。
C# Code --> C# compiler --> CIL
,因为
CIL = Managed
当放入其上下文时,还有
Native Code = Unmanaged
请注意,Managed Code
完全不同,refers to the source code。
如果要扩展它,则更正的完整过程为:
.NET Code --Compiler--> CIL (Managed) --JIT/NGEN--> Native Code (Unmanaged)
参考文献:
答案 2 :(得分:3)
答案 3 :(得分:2)
为Windows编写程序时,可以编写以下两种代码之一:托管代码和本机代码。本机代码直接编译为可执行机器或.dll,而托管代码是以.NET运行时为目标的代码(换句话说,其编译形式,称为程序集,是包含CIL指令的文件)。在运行时,CIL由JIT编译器转换为机器代码并执行。托管和本机之间的区别与语言(及其编译器)所针对的内容有关。本机代码以机器本身为目标,因为它被编译成一组直接机器指令。另一方面,C#编译器将您的代码编译为CIL,因为C#语言编译器以.NET运行时为目标。然后可以说C#是一种“托管语言”,其中编写的任何代码都是“托管代码”。例如:
C src -> gcc.exe -> .exe containing a machine binary -> processor
C# src -> csc.exe -> .exe assembly containing CIL -> CLR/JIT -> processor
我认为使用术语“托管”的原因是因为构成代码的指令最终由.NET运行时处理,而不是由处理器直接执行。将源代码编译到CIL的额外步骤本身并不是什么使得代码得到管理:相反,程序永远不会被处理器直接执行的事实。 CIL正是允许多种不同托管语言以同一运行时为目标的原因。
我知道这比仅仅说“托管语言编译成CIL”要多得多,但那是因为我并不认为这是对代码管理的完全准确的描述。 Java字节码类似于CIL,但存在可以原生执行字节码的实际“Java处理器”。对于.NET CIL也可以设想这样的处理器,这意味着编译成CIL并在这样的机器上运行的代码将变为本机的。您的代码必须通过CLR处理的事实才能使其得到管理。 CIL恰好是代码必须转换为的格式,因为运行时可以执行它。
答案 4 :(得分:2)
我不会在这里详细介绍,因为其他人已经介绍了很多细节,但我想澄清一些其他答案没有真正解释得很好或正确的观点。这在很大程度上是迂腐的,对于99.99999%的情况,您可以想到“C#和CIL / MSIL是托管代码”,但这有一些细微之处。
首先,CIL / MSIL被称为“中间语言”,这意味着它是一种计算机语言,用作源代码和最终本机代码之间的中间步骤。但是,这不是必须的。我听说过实验项目,他们创建了一个CPU,它直接执行CIL(或称为Java Byte Code的Java等价物)而不先将其转换为原生形式(基本上,CIL是本机形式)。
托管代码是指由某种托管运行时“管理”的代码。这通常意味着代码是垃圾收集的,并且具有某种安全层,可以防止缓冲区溢出和本机代码中可能出现的其他类型的问题。在.net中,这称为公共语言运行时(CLR)
在过去,这曾经被称为“虚拟机”以及为什么java环境被称为JVM,尽管该术语现在在很大程度上是用词不当。如今,使用JIT(即时)编译器,没有实际的“虚拟机”,而是一层代码“包装”本机编译代码,以确保您不破坏规则,并在之后进行清理你的代码。它还抽象出一些特定于平台的东西,以便CIL不必担心它们。
因此,托管代码指的是在托管运行时中运行的代码的概念。当CIL在运行时(例如.NET运行时环境)中运行时,它被视为托管代码。
C#和VB.NET通常被认为是“托管语言”,因为它们通常被编译为CIL并在托管运行时下运行。但是,这不一定是这种情况(尽管如果遵循规范的字母,它可能必须是这种情况)。例如,有些编译器会直接将c#编译为本机代码而没有中间级别,并且C#的运行时解释器根本不编译代码,而是在运行时“解释”它。
因此,要点是托管代码和CIL是两个不同的东西,但它们是相关的。