http://www.codeguru.com/Csharp/.NET/cpp_managed/article.php/c4871

本文内容

  • 什么是托管代码?
  • 什么是非托管代码?
  • 什么是本地代码?
  • 托管代码意味着托管数据?

虽然该文章写的时间比较早,但是完全可以说明问题。

2003 年 4 月 24 日 VS 2003(之前称为 Everett)发布,很多开发者愿意考虑使用托管代码的新技术。但是对这个新技术有点迷茫,特别是 C++ 开发者。因为,正如我之前指出的,C++ 是特殊的。

什么是托管代码(Managed Code)?


托管代码是 Visual Basic .NET 和 C# 编译器创建。它们编译成中间语言(IL),而不是直接在计算机上运行的机器代码。IL 被保存在一个称为程序集中,以及描述代码的类、方法、和属性(如安全性要求)的元数据文件。在 .NET 里,程序集是“一站式(one-stop-shopping)”部署的单元。可以将程序集直接复制到另一台服务器上进行部署。

托管代码运行在公共语言运行库(Common Language Runtime,CLR)。CLR 为正在运行的代码提供多种服务。在通常代码事件中,它首先加载和验证程序集,确保 IL 正确。然后,当程序集运行,方法被调用时,CLR 安排它们被编译为适合机器的机器码,并缓存该机器码,以便下次被调用时使用。这被称为 Just In Time,或 JIT compiling,或简称 Jitting。

当程序集运行时,CLR 继续提供诸如安全、内存管理、线程和其他的服务。应用程序是由 CLR 来管理的。

Visual Basic .NET 和 C# 只能产生托管代码。如果你用的是这些应用程序,那么你就正在使用托管代码。Visual C ++ .NET 也能产生托管代码,就是当你创建一个项目,选择名为“.Managed”开始的应用程序类型,如“.Managed C++ application”。

什么是非托管代码(Unmanaged Code)?


非托管代码是你以前用 Visual Studio .NET 2002 创建的代码。现在你还有很多 Visual Basic 6、Visual C ++ 6,甚至是使用了 15 年的老 C 编译器产生的非托管代码。非托管代码直接被编译成机器码,跟你具有相同或几乎相同的芯片的机器上都能运行。但是,它不能从不可见的运行时里获得诸如安全或内存管理等服务,而只能从操作系统获得,通过调用 Windows SDK 提供的 API。最近,有越来越多的非托管应用程序通过 COM 调用获得操作系统的服务。

不同于 Visual Studio 2003 中的其他语言,Visual C ++ 可以创建非托管应用程序。当你创建一个项目,选择以 MFC、ATL 或 Win32 开头的应用程序,就创建了一个非托管的应用程序。

这导致一些混淆,也就是说,当创建一个托管的 C++ 应用程序时,那么生成结果是一个 .exe 扩展名的 IL 装配文件。当你创建一个 MFC 应用程序,生成结果是一个本地代码(native code)的 Windows 可执行文件,扩展名也是 .exe。这两个文件的内部布局完全不同。你可以使用中间语言反汇编工具(Intermediate Language Disassembler)ildasm,查看内部装配,以及元数据文件和 IL。在非托管的 .exe 文件使用 ildasm,你会被告知没有有效的 CLR 头,不能反汇编——虽然扩展名相同,但文件完全不同。

什么是本地代码(Native Code)?


本地代码在两种情况下使用。许多人把非托管代码作为本地代码的同义词:用旧的编译工具或是 Visual C ++ 生成代码,不会运行在 CLR 上,而是在计算机本地。这可能是一个完整的应用,也可能是一个 COM 组件或通过 COM Interop 或 PInvoke 由托管代码调用的 DLL。COM Interop 和 PInvoke 是强大的工具,确保,当你将旧代码移动到新环境时,仍然可以使用。我更喜欢说非托管代码。从这个意义上,因为它强调的是代码不会得到运行时的服务。例如,托管代码中代码访问安全性(Code Access Security),会阻止代码从另一个服务装载代码,防止破坏性的行为。如果你的应用程序从另一个服务加载非托管代码,就无法得到这种保护。

本地代码的另一个使用是描述了 JIT 编译器的输出,机器代码事实上是运行在运行时上。这是托管的,不是 IL,而是机器码。因此,不能假设本地代码等同于非托管代码。

托管代码意味着托管数据?


对于 Visual Basic 和 C#,生存期问题很简单,因为你别无选择。当你声明一个类,在托管堆上创建该类的实例,而垃圾回收器关心该实例的生存期问题。但是在 Visual C++,你是有选择的。即使你创建一个托管应用程序,也可以由你决定类是否是一个托管类型或一个非托管类型。

下面是一个非托管类型:

class Foo

{

    private:

        int x;

    public:

        Foo(): x(0){}

        Foo(int xx): x(xx) {}

};

下面是一个托管类型:

__gc class Bar

{

    private:

        int x;

    public:

        Bar(): x(0){}

        Bar(int xx): x(xx) {}

};

唯一的区别是Bar定义前边的 __gc 关键字,但却有很大不同。关于 __gc 关键字参见MSDN:ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_fxintro/html/6a1f9b6c-9983-4722-8b58-13e9af2a1339.htm

托管类型是可以被回收的。它们必须用new来创建,不在堆上。因此,下面是对的:

Foo f;

但下面是不允许的:

Bar b;

如果我必须在堆上创建Foo的一个实例,那一定要记着清除它:

Foo* pf = new Foo(2);

// . . .

delete pf;

在C ++编译器实际上使用两个堆,一个是托管的,一个是非托管的,使用重载的new操作符,当创建用一个new创建实例时,来确定分配的内存在哪里。如果在堆上创建Bar的一个实例,那么可以忽略它。垃圾回收器将会回收它。在 Visual C++,你是有选择的。

.NET 托管、非托管、本地:这些代码有什么区别?的更多相关文章

  1. 托管非托管Dll动态调用

    原文:托管非托管Dll动态调用 最近经常看到有人问托管非托管Dll调用的问题.对于动态库的调用其实很简单.网上很多代码都实现了Dll的静态调用方法.我主要谈论下动态库的动态加载. 对于托管动态库,实现 ...

  2. .Net 程序在自定义位置查找托管/非托管 dll 的几种方法

    原文:.Net 程序在自定义位置查找托管/非托管 dll 的几种方法 一.自定义托管 dll 程序集的查找位置 目前(.Net4.7)能用的有2种: #define DEFAULT_IMPLEMENT ...

  3. C# 托管非托管资源释放

    1.C#几乎所有对象都为托管对象,不同点是有的对象封装了非托管资源. 2.C#大部分对象在进行垃圾回收时都可以回收,包括非托管资源,因为非托管资源都已经通过C#类进行了封装,会将非托管资源的释放放在析 ...

  4. C#的托管与非托管大难点

    托管代码与非托管代码 众所周知,我们正常编程所用的高级语言,是无法被计算机识别的.需要先将高级语言翻译为机器语言,才能被机器理解和运行.在标准C/C++中,编译过程是这样的:源代码首先经过预处理器,对 ...

  5. C#的三大难点之二:托管与非托管

    相关文章: C#的三大难点之前传:什么时候应该使用C#?​C#的三大难点之一:byte与char,string与StringBuilderC#的三大难点之二:托管与非托管C#的三大难点之三:消息与事件 ...

  6. 编写高质量代码改善C#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源

    建议50:在Dispose模式中应区别对待托管资源和非托管资源 真正资源释放代码的那个虚方法是带一个bool参数的,带这个参数,是因为我们在资源释放时要区别对待托管资源和非托管资源. 提供给调用者调用 ...

  7. 重学c#系列——c# 托管和非托管资源与代码相关(四)

    前言 这是续第三节. 概况垃圾回收与我们写代码的关系: 强引用和弱引用 针对共享 Web 承载优化 垃圾回收和性能 应用程序域资源监视 正文 强引用和弱引用 垃圾回收器不能回收仍在引用的对象的内存-- ...

  8. C# 托管和非托管混合编程

    在非托管模块中实现你比较重要的算法,然后通过 CLR 的平台互操作,来使托管代码调用它,这样程序仍然能够正常工作,但对非托管的本地代码进行反编译,就很困难.   最直接的实现托管与非托管编程的方法就是 ...

  9. 斗地主你什么时候才会托管?(.NET中的托管于非托管)

    文章部分引自<.NET4.0面向对象编程漫谈(基础篇)>第1章.NET面向对象编程基础(作者:金旭亮) 无意间看到一位四五岁左右小朋友在玩斗地主,总开始到结束,她一直都在使用“提示”(托管 ...

随机推荐

  1. 清华梦的粉碎—写给清华大学的退学申请(转自王垠Blog)

    清华梦的诞生 小时候,妈妈给我一个梦.她指着一个大哥哥的照片对我说,这是爸爸的学生,他考上了清华大学,他是我们中学的骄傲.长大后,你也要进入清华大学读书,为我们家争光.我不知道清华是什么样子,但是我知 ...

  2. 在ASP.NET MVC控制器中获取链接中的路由数据

    在ASP.NET MVC中,在链接中附加路由数据有2种方式.一种是把路由数据放在匿名对象中传递: <a href="@Url.Action("GetRouteData&quo ...

  3. iReport数据库连接找不到驱动

  4. 使用android 隐藏类和方法

    在应用程序中添加与android.jar包相同的包目录,添加要隐藏类和方法.保证能编译通过就可以.

  5. 2018房地产沉思录 z

    在中国,房价问题几乎有一个铁律:越调控越暴涨. 刚刚进入5月,全国各地发布的调控政策数量就已经超过了115个.仅4月份,全国各种房地产调控政策合计多达33次,25个城市与部门发布调控政策,其中海南.北 ...

  6. 便利的初始化view以及设置tag值

    便利的初始化view以及设置tag值 效果 源码 https://github.com/YouXianMing/iOS-Project-Examples 中的 SetRect // // Access ...

  7. 同志亦凡人第五季/全集BQueer As Folk 5迅雷下载

    同志亦凡人 第五季 Queer as Folk Season 5 (2005) 本季看点:这是一群生活在匹兹堡男人和男人,女人和女人的故事.在他们的王国里有各色人物.王国的国王Brian(葛尔?哈罗德 ...

  8. 犯罪现场调查第一季/全集CSI迅雷下载

    英文译名 CSI (第1季) (2000首播)CBS. 本季看点:<犯罪现场调查>赌城拉斯维加斯吸引着做发财梦的人,也吸引着形形色色的罪犯,该市警察局的犯罪现场调查局在全美国名列第二.该剧 ...

  9. libgdx 环境搭建

    1:环境搭建: (1)首先进入官网,http://libgdx.badlogicgames.com/download.html  点击下方的Releases.进行下载最新的版本号就可以. 这个为我们开 ...

  10. Material Designer的低版本兼容实现(九)—— Float Button & Small Float Button

    5.0一个新特性就是出现了这么一个圆形的悬浮指示按钮,这个按钮可以用来体现一个全局的重要功能,比如添加账户什么的.这个按钮有两种大小,一种是正常的按钮大小,一种是小型的按钮.官方文档中介绍的是小心的按 ...