【问题标题】:What exactly is "managed" code?究竟什么是“托管”代码?
【发布时间】:2008-09-11 23:38:58
【问题描述】:

我已经编写 C/C++ 代码近 20 年了,我知道 Perl、Python、PHP 和一些 Java,并且我正在自学 JavaScript。但我从未做过任何 .NET、VB 或 C# 的东西。 托管代码到底是什么意思?

维基百科describes it简单来说

在虚拟机管理下执行的代码

它特别指出Java(通常)是托管代码,所以

  • 为什么该术语似乎只适用于 C#/.NET?
  • 能否将 C# 编译成包含 VM 的 .exe,还是必须将其打包并提供给另一个 .exe(类似于 java)?

同样,

  • .NET 是一种语言还是一种框架,这里的“框架”究竟是什么意思?

好的,这不仅仅是一个问题,但对于像我一样长期从事该行业的人来说,我现在感觉相当 N00B-ish...

【问题讨论】:

标签: c# .net vb.net managed-code


【解决方案1】:

当您将 C# 代码编译为 .exe 时,它​​会被编译为通用中间语言 (CIL) 字节码。每当您运行 CIL 可执行文件时,它都会在 Microsoft 的公共语言运行时 (CLR) 虚拟机上执行。所以不,不可能将 VM 包含在您的 .NET 可执行文件中。您必须在将运行您的程序的任何客户端计算机上安装 .NET 运行时。

要回答您的第二个问题,.NET 是一个框架,因为它是一组库、编译器和 VM,不是特定于语言的。因此,您可以使用 C#、VB、C++ 和任何其他具有 .NET 编译器的语言在 .NET 框架上进行编码。

https://bitbucket.org/brianritchie/wiki/wiki/.NET%20Languages

以上页面列出了具有 .NET 版本的语言,以及指向其页面的链接。

【讨论】:

  • 由于.NET中的编译是一个两步过程,我们可以说语言编译器(例如c#编译器)编译成IL代码的代码也称为“托管代码”吗?
【解决方案2】:

我不认为只有您对 .Net 是什么感到困惑。已经有其他答案应该让你知道,但我会把这些信息扔给其他人。

要查看“真正”的 .Net 是什么,只需转到 c:\Windows\Microsoft.Net\Framework

在那里,您将看到特定于您安装的版本的文件夹。例如,如果已安装,请进入 v2.0.xxxx 文件夹。

在那个文件夹中是框架。你基本上会看到一堆 .exe 文件和 .dll 文件。所有以 System.*.dll 开头的 DLL 文件本质上都是 .Net 框架。

您将在该文件夹中看到的 .exe 文件是用于开发人员和编译器的实用程序。你提到了 C#。找到 csc.exe 文件。那是你的 C# 编译器。

构建程序非常简单。将以下代码放入 hello.cs 文件中。

using System;
class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("hello world");
        }
    }

然后在命令行输入> csc hello.cs

这将为您生成一个 .exe 文件。运行它,它显然会吐出'hello world'。

显示 Console.WriteLine() 的行正在调用框架。 Console 是一个存在于 System 命名空间中的对象,而 WriteLine() 是一个静态方法。

这是该 Console.WriteLine() 方法的反汇编代码:

[HostProtection(SecurityAction.LinkDemand, UI=true)]
public static void WriteLine(string value)
{
    Out.WriteLine(value);
}

当人们说“我应该使用 PHP 还是 .Net?”或“我应该使用 Python 还是 .Net”之类的话时,您会开始发现讨论的问题是错误的。他们显然是将语言与框架进行比较。 C# 是一种语言,它只是可用于在 .Net 平台之上编写代码的众多语言之一。 Console.WriteLine() 的相同方法可以从 C#、VB.Net、Pascal、C++、Ruby、Python、F# 和任何其他已在 .Net 平台上运行的语言调用。

希望对你有帮助。

-基思

【讨论】:

    【解决方案3】:

    主要是指您所有的内存分配都是为您“管理”的。如果您使用托管代码,则不必担心在使用完对象后会释放它们。简单地允许它们超出范围将意味着 VM 最终将认识到不再有任何对它们的引用,并且垃圾会收集它们并将内存返回给系统。

    另一方面,非托管代码只会“泄漏”,除非您在丢弃引用之前明确释放指针。

    【讨论】:

      【解决方案4】:

      它主要用于描述 .NET,因为这是 Microsoft 选择将 .NET 与 C/C++ 和其他旧语言区分开来的术语。微软之所以选择它是因为它不是一个通常与 Java 相关联的术语,因为他们不想强调 C#/.NET 和 Java 之间的相似之处(而不是将其称为“虚拟机代码”之类的东西听起来更像Java)。基本上,“托管代码”的使用是营销驱动的,而不是技术驱动的术语。

      【讨论】:

        【解决方案5】:

        特别是在 .NET 和 Visual C++ 下,您可以同时拥有非托管和托管代码。这些术语指的是分配和“管理”内存的方式。

        非托管代码将是您习惯使用的 C++ 代码。动态内存分配和显式释放内存。 .NET 运行时不会为您管理内存,因此是“非托管”的。

        另一方面,托管代码由运行时管理。您在需要的地方分配内存(通过声明变量,而不是内存空间),运行时垃圾收集器确定何时不再需要并清理它。垃圾收集器还将移动内存以提高效率。运行时为您“管理”这一切。

        如上所述,可以编写托管和非托管代码。

        非托管:

        class Bar : public Foo {
            private:
                    int fubar;
            public:
                    Bar(int i) : fubar(i) {}
                    int * getFubar() { return * fubar; }
        }
        

        托管:

        public ref class Bar :  public Foo
            private:
                    int fubar;
            public:
                    Bar(int i) : fubar(i) {}
                    int ^ getFubar() { return ^ fubar; }
        }
        

        注意到裁判了吗?这几乎指定了一个托管类。但是,当您混合使用这两种代码时,它会变得非常混乱。例如,您希望将引用指针 (^) 指针的托管等效项保存到非托管类中的图片框控件。由于垃圾收集器可以移动内存,下次您尝试取消引用图片框时,它就找不到了。运行时不会告诉您的非托管代码它的内存更改。

        因此,您需要将托管对象固定在内存中,以允许您的非托管代码跟踪它。然后是拆箱和其他各种怪癖,可以让您将两者混合在一起。代码复杂度巨大!

        正式地,托管/非托管可能归结为代码在 .NET 堆栈上的执行方式。但是,如果您来自 c++ 背景,我希望这对您来说更相关。

        【讨论】:

          【解决方案6】:

          托管意味着代码没有编译为本机代码,因此在虚拟机的支持下运行。 Java 编译成一种称为字节码的中间格式,Java VM 知道如何解释和执行这种格式。所有 .NET 语言都做类似的事情,编译为 .NET 运行时解释的 IL(中间语言)。这有点令人困惑,因为 .NET IL 有 .dll 和 .exe 文件结尾。

          【讨论】:

            【解决方案7】:

            托管一词通常仅适用于 .NET,因为 Microsoft 使用该术语。 Microsoft 通常不使用术语“虚拟机”来指代 .NET 托管执行环境。

            .NET 的“字节码”(IL)与 Java 字节码有些不同,它被明确设计为在托管环境中执行之前编译为本机代码,而 Java 被设计为解释性的,但平台的概念- 独立代码类似。

            “.NET 框架”基本上是微软提供的一组庞大的库,包含数千个可用于开发应用程序的类。

            编译后的 C# .exe 包含独立于平台的代码,可以在任何与 .NET 兼容的环境中运行,包括 Mono。但是,运行时通常与使用它的应用程序分开分发。

            【讨论】:

              【解决方案8】:

              冒着冒犯某些人的风险,我怀疑使用了托管这个词,因此他们可以使用非托管这个词而不是编译。虽然托管可能意味着更多,但实际上它似乎主要用于区分几乎即时编译的代码(作为曾经解释或 pcode 的替代)和本机编译代码。

              或者换一种方式,你更喜欢使用哪个:

              a) 可能对系统造成无法控制的事情的非托管代码。

              b) 快速、可靠且接近操作系统的本机编译代码。

              当然,它们实际上是一回事。

              【讨论】:

                【解决方案9】:

                类似地,.NET 是一种语言还是一种框架,“框架”在这里究竟是什么意思?

                .NET 是微软当前的企业软件平台。它包括:

                • 用于访问 Windows 功能的单一通用界面:

                o The .NET Framework Class Library (FCL).
                o The FCL provides a rich set of high-level functionality for developers.
                

                • 用于执行 .NET 应用程序的单一通用语言和运行时:

                o Common Language Runtime (CLR) executes Common Intermediate Language (CIL).
                o The CLR is God: it runs, controls, and polices everything.
                

                • 为开发 .NET 应用程序选择多种语言:

                o Every development language is compiled to CIL, which is run by the CLR.
                o C# and VB are the two main development languages.
                

                【讨论】:

                  【解决方案10】:

                  .NET 是一个框架。公共语言运行时 (CLR) 执行在编译解决方案时生成的 Microsoft 中间语言 (MSIL) 代码(即,它不会编译为机器代码)。您不能在 exe 中包含 API,也不想包含它,因为它非常大。这里的主要好处是内存管理(以及其他一些安全优势,可能还有其他我不知道的优势。)

                  【讨论】:

                    【解决方案11】:

                    我可以回答框架问题。 .NET 是一个框架,C#、VB.NET 等是语言。基本上.NET 提供了一个通用的库平台来调用(所有系统...... dll),任何使用.NET 的语言都可以调用。所有 .NET 语言都被编译成 MSIL(Microsoft Intermediate Language,俗称 IL),然后可以在安装了相应 .NET 框架的任何 PC 上运行。

                    【讨论】:

                      【解决方案12】:

                      .NET 是一个框架。 它可以用于多种语言(VB.NET、C#、IronPython、boo 等)

                      .NET 始终按解释执行,不,您不能在 .exe 中包含“VM”。任何希望运行您的 .NET 应用程序的用户都必须安装该框架。

                      【讨论】:

                        【解决方案13】:

                        它可以引用由虚拟机执行的任何代码,而不是直接由 CPU 执行。

                        我认为这可以实现垃圾收集和数组边界检查等功能。

                        【讨论】:

                          【解决方案14】:

                          我个人认为“框架”这个词有点用词不当。

                          .NET 是一个“平台”,由一个执行环境(CLR 虚拟机)和一组库组成。它与 Java、Perl 或 Python 完全类似(它们都没有被称为“框架”)。

                          在大多数情况下,“框架”一词用于诸如 Spring、Struts 或 QT 之类的项目,它们位于像库一样的平台之上(即不提供自己的执行环境)。

                          但与“库”不同的是,框架旨在重新定义底层平台的基本操作。 (Spring 的依赖注入违背了普通 Java 代码的构造函数调用逻辑。QT 的信号槽实现违背了普通的 C++ 代码。)

                          我知道我只是一个迂腐的混蛋,但对我来说,.NET 不是一个框架。这是一个平台。

                          【讨论】:

                            【解决方案15】:

                            托管代码--MSIL 和 IL 和托管代码是相同的。当我们构建应用程序时,会在 Bin 文件夹中生成 .dll 或 .exe 文件。这些文件称为托管代码。稍后将这些文件提供给 CLR生成操作系统可以理解的本机代码。

                            【讨论】:

                            • 其他答案已经涵盖了这一点。仅当您的帖子提供附加价值广告时才添加。
                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 2014-10-28
                            • 2012-08-27
                            • 2010-11-12
                            • 2011-03-18
                            • 2011-01-22
                            • 1970-01-01
                            相关资源
                            最近更新 更多