【问题标题】:IS C++ converted into MSIL?C++ 是否转换为 MSIL?
【发布时间】:2009-03-27 03:03:25
【问题描述】:

我长期从事 C# 和 .Net 开发,一直在玩学习 c++ 的想法。

我一直在考虑这个问题的主要原因之一是,C++ 可以比使用 .Net 框架的应用程序快多少。但是我是否正确假设如果我在 Visual Studio 中编写 C++ 应用程序,和/或在 C++ 应用程序中引用 .Net 库,该 C++ 会在 MSIL 中转换(就像 C# 一样) - 因此我会失去任何好处从里面编码?

所以我的问题实际上是这样的:引用 .Net 程序集的应用程序的 C++ 组件是以“传统”方式编译还是编译到 MSIL 中?

【问题讨论】:

    标签: .net c++ compiler-construction cil


    【解决方案1】:

    嗯,它比这更复杂一些。 实际上,支持 .NET 的 C++ 有两个完全不同的版本。

    旧的 C++ 托管扩展是 Visual C++ 2002/2003 中唯一可用的选项。它在选项 /clr:oldSyntax 下的较新编译器中可用。它有点笨拙,因为它努力与标准 C++ 集成,所以所有新关键字(而且有很多)都以双下划线等为前缀。这个编译器生成的代码是本机代码和 MSIL 代码的混合,称为 IJW“它只是工作”。

    名为 C++/CLI 的新语言是 Visual C++ 2005 及更高版本中可用的一种全新语言。最重要的是,它支持多种代码生成模式。 /clr 选项再次生成本机代码和 MSIL 代码的 IJW 混合。 /clr:pure 会导致仅托管程序集,尽管它可能会将本机类型转换为相应的 .net 结构。因此,代码可能不是类型安全的,并且可以使用指针算术,很像带有 /unsafe 的 C#。 最严格的选项是 /clr:safe,它生成类型安全、可验证的仅 MSIL 程序集,就像 C# 编译器所做的一样(即没有 /unsafe)。

    有关 MC++ 和 C++/CLI 之间的区别,请参阅wikipedia

    有关编译器开关的说明,请参阅MSDN

    PS。 .NET 字节码称为 MSIL(Microsoft 中间语言)或 CIL(通用中间语言)。 MIL 可以代表媒体集成层,它是 WPF 和 Vista 桌面窗口管理器使用的未记录的低级库。

    【讨论】:

      【解决方案2】:

      将概念分开可能是个好主意。

      首先,C++ 是一门语言,它没有具体说明应该针对什么平台。原则上,直接的 C++ 代码可以编译为本机 x86 汇编程序、Java 字节码、MSIL 或您想想到的任何其他内容。我相信 Adob​​e 最近制作了一个生成 Flash 字节码的 C++ 编译器。

      其次,由于典型的优柔寡断,Microsoft 创建了两种针对 .NET 的 C++ 派生语言。首先,他们制作了“C++ 托管扩展”。然后他们认为它很糟糕,抛弃了它,并试图假装它从未存在过。

      现在他们对 .NET 风格的 C++ 的最佳选择是 C++/CLI,但 它不是 C++。它以多种非标准方式扩展和更改语言。 (而且我相信 C++ 标准委员会要求他们更改名称以避免混淆。但他们没有)

      Visual Studio 2005 和更新版本支持 C++/CLI。 (在“添加项目”中,它们列在 Visual C++ -> CLR 下)

      然而(你没想到这么简单吧?),微软又做了一次。在指定 C++/CLI(这实际上是一种设计合理的将 C++ 与 CLI 集成的尝试)之后,他们意识到几乎没有人使用它! 事实证明,即使是 C++ 程序员,在 .NET 中工作时通常也更喜欢使用 C#,否则更喜欢使用适当的原生 C++。

      所以现在,他们专注于使 native C++ 和 .NET 之间的互操作更简单、更强大。但是,C++/CLI 不太可能消失。它有效,在某些情况下它很有用。这不是他们最初希望的 C++ 杀手。

      Visual Studio(自始至终)还支持本机 C++ 应用程序,编译为 x86 机器代码,不受 .NET 污染。这些列在 Visual C++ -> Win32 下的“添加项目”对话框中。

      所以如果你想学习 C++,你有两个选择: 学习 C++/CLI,这将您限制为仅限 MS 的语言,是的,生成 MSIL 而不是本机机器代码,并且需要 .NET 才能运行,通常不值得费心,因为如果您要依赖在 .NET 上无论如何,为什么不用 C# 编写?

      或者学习正确的 C++,它完全独立于 .NET,不能直接引用 .NET 程序集。

      关键点是它们是不同的语言。要么编译为 C++/CLI,这意味着编译器将允许你引用 .NET 程序集,并生成 MSIL 代码,要么编译为 C++,在这种情况下,.NET 世界不存在。

      最后,请注意。尽管我上面的措辞(“正确的 C++”和“不受 .NET 污染”),C++ 并不是“更好”。在许多情况下,它也不是更快。 C++ 有更快的潜力,但它更多地取决于程序员。

      C# 编译器可以将几乎所有内容转换为相当高效的代码。 另一方面,C++ 充满了陷阱,会使您的代码比等效的 C# 慢

      http://blogs.msdn.com/ricom/archive/2005/05/10/416151.aspx 及其引用的博客文章值得任何对用两种语言编写的类似代码的性能感兴趣的人阅读。

      只有一个领域 C++ 应用程序会始终更快,那就是启动时间。 .NET 应用程序可能必须加载 .NET 框架并 JIT MSIL 代码,而本地应用程序...刚刚启动。

      但除此之外,假设 C++ 会更快可能是错误的。它可以,因为它给了你更多的控制权。但通常,这只是意味着编译器无法将您从您在代码中创建的低效率中拯救出来。

      【讨论】:

        【解决方案3】:

        This 是一个关于托管与非托管 C++ 的很好(如果过时的话)的讨论。

        简而言之,C++ 既可以是托管的(编译为 MIL),也可以是非托管的(编译为本机代码)。

        【讨论】:

          【解决方案4】:

          无论您想学习 C++ 的原因是什么,了解更多的语言总是好的,因为它拓宽了您的思维,因此学习 C++ 本身就是一堂宝贵的课程。

          使用 C++,您可以将其作为 .NET 应用程序 C++/CLI 或本机运行。它只是 Visual Studio 中的一个编译器开关,但是两者之间存在很多语法差异。我个人认为学习这两种口味很有用。

          在您的项目中选择哪个取决于一些要求,例如如果您的程序需要与其他托管模块(例如用 C# 编写的模块)进行交互,则最好使用 C++/CLI 以避免在托管代码和非托管代码之间进行一些开销切换。

          【讨论】:

            【解决方案5】:

            C++ 组件不能轻易引用 .Net 程序集(您需要使用 COM)。托管 C++ 被编译为 CIL,并具有与 C# 相同的性能配置文件。

            对于大多数代码,在相同级别的优化中,C++ 的速度大约快 10%,但是 C# 需要一半的时间来编写和调试,因此在相同的时间段内,我认为您可以实施的优化将使 C# 更快。 ..

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-03-25
              • 2010-09-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多