随着Visual Studio .NET 2003在四月24号的发布,许多开发者开始考虑使用一项被成为托管 代码 的新技术。但是对于C++开发者来说,可以会 遇到一些麻烦。因为C++是比较特殊的。

什么是 托管 代码 ?

托管 代码 就是Visual Basic .NET和C#编译器编译出来的代码。编译器把代码编译成中间语言(IL),而不是能直接在你的电脑上运行的机器码。中间语言被封装在一个叫程序集 (assembly)的文件中,程序集中包含了描述你所创建的类,方法和属性(例如安全需求)的所有元数据。

这个程序集是.NET世界中的一个一站式购物(译者注:就是程序集具有自描述性)部署单元。你可以拷贝这个程序集到另一台 服务器上部署它--通常来说,这个拷贝的动作就是部署流程中唯一的一个操作。

托管 代码 在公共语言运行库(CLR)中运行。这个运行 库给你的运行代码提供各种各样的服务,通常来说,他会加载和验证程序集,以此来保证中间语言的正确性。当某些方法被调用的时候,运行库把具体的方法编译成 适合本地计算机运行的机械码,然后会把编译好的机械码缓存起来,以备下次调用。(这就是即时编译)

随着程序集的运行,运行库会持续地提供各种服务,例如安全,内存管理,线程管理等等。这个程序被“托管 ”在运行库中。

Visual Basic .NET和C#只能产生托管 代码 。如果你用这类语言写程序,那么所产生的代码 就是托管代码。如果你愿意,Visual C++ .NET可以生成托管代码。当你创建一个项目的时候,选择名字是以.Managed开头的项目类型。例如.Managed C++ application。

什么是非 托管 代码 ?

非托管 代码 就是在Visual Studio .NET 2002发布之前所创建的代码。例如Visual Basic 6, Visual C++ 6, 最糟糕的是,连那些依然残存在你的硬盘中、拥有超过15年历史的陈旧C编译器所产生的代码都是非托管代码。托管代码直接编译成目标计算机的机械码,这些代 码只能运行在编译出它们的计算机上,或者是其它相同处理器或者几乎一样处理器的计算机上。非托管代码不能享受一些运行库所提供的服务,例如安全和内存管理 等。如果非托管代码需要进行内存管理等服务,就必须显式地调用操作系统的接口,通常来说,它们会调用Windows SDK所提供的API来实现。就最近的情况来看,非托管程序会通过COM接口来获取操作系统服务。

跟Visual Studio平台的其他编程语言不一样,Visual C++可以创建非托管 程序。当你创建一个项目,并且选择名字以 MFC,ATL或者Win32开头的项目类型,那么这个项目所产生的就是非托管程序。

这样子会导致一些混淆:当你创建一个托管 的C++程序,那么构建出来的是一个中间语言 程序集和一个扩展名为.exe的可执行文件。当你创建一个MFC程序,构建出来是一个Windows原生代码 的可执行文件,这个文件的扩展名也 是.exe。这两个文件的内部结构是完全不一样的。你可以用中间语言反汇编器(ildasm)来查看程序集的内部以及中间语言的元数据。如果尝试用中间语 言反汇编器来查看一个非托管可执行文件,那么改反汇编器会告诉你这个可执行文件没有包含一个合法的CLR头,所以不能被反编译。可见,这两个文件虽然有相 同的扩展名,但是它们是完全不一样的。

原生 代码 又是什么呢?

原生代码 这个短语可以用在两个不同的上下文中。很多人 会把原生代码跟非托管代码看作是同一个意思:用较老的工具构建的代码,故意采用Visual C++并使直接运行在计算机上,而且不运托管在运行库中。这可以是一个完整的程序,或者是一个COM组件,又或者是一个可以被托管代码利用COM Intero或者平台调用(PInvoke)所调用的DLL文件,COM Intero或者平台调用(PInvoke)可以帮助你在迁移到新的技术平台下依然能重用老代码的两个强大工具。我更愿意说是非托管代码,因为这强调的是 那些不能利用运行库所提供的服务的代码。例如在托管代码中,代码访问安全服务可以防止在另一个服务器上装载的代码运行特定的操作。如果你的代码运行的是非 托管代码,那么你没法利用这样的保护服务。

原生代码 的另一个意思是描述即时编译器的输出,那些实 际上运行在运行库中的机械码。这些代码是托管代码,但是并不是中间语言,而是机械码。所以不要简单地假设原生就是等同于非托管。

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

对于Visual Basic和C#来说,生活是简单的,因为你没有其它 选择。当你在那些语言里面声明一个 类,那么这个类的实例会在托管 堆中被创建,垃圾收集器(GC)会帮我们管理 这些对象的回收。但是在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关键字。这个关键字会给代码 带来巨大的区别。

托管 类型是可以被垃圾回收器所回收的。他们必须 要用关键字new来创建,永远都不会在栈中出现。所以下面这行代码 是合法的:

Foo f;

但是这一行代码 就是非法的:

Bar b;

如果我在堆中创建一个Foo对象,那么我必须要负责清理这个对象:

Foo* pf = new Foo(2);
    // . . .
    delete pf;

C++编译器实际上会用两个堆,一个托管 堆和一个非托管堆,然后通过对new操作符的 重载来实现对创建不同类型类的实例,分配不同的内存。

如果我在堆里面创建一个Bar实例,那么我可以忽略它。当没有其他代码 在使用它的时候,垃圾回收器会自动清理这个 类,释放其占用的资源。

对于托管 类型会有一些约束:它们不能实现多重继承,或 者继承与非托管类型;它们不能用friend关键字来实现私有访问,它们不能实现拷贝构造函数。所以,你有可能不想把你的类声明为托管类型。但是这并不意 味着你不想让你的代码 成为托管代码。在Visual C++中,你可以选择。

摘自:http://alifens198345.blog.163.com/blog/static/1167991772009879414856/

浅析托管与非托管C++代码相关推荐

  1. 有关Dispose,Finalize,GC.SupressFinalize函数-托管与非托管资源释放的模式

    //这段代码来自官方示例,删除了其中用处不大的细节using System; using System.ComponentModel;/**** 这个模式搞的这么复杂,目的是:不管使用者有没有手动调用 ...

  2. .net中的托管、非托管

    1.托管代码Managed Code 托管代码是编译器创建,被编译成中间语言(IL),IL被保存在程序集(描述代码的类.方法它和属性的元数据文件)中. 托管代码运行在CLR中: 托管代码独立于平台和语 ...

  3. 托管和非托管的区别。

    NET Framework 是一种新的计算平台,它简化了在高度分布式 Internet 环境中的应用程序开发..NET Framework 旨在实现下列目标: 提供一个一致的面向对象的编程环境,而无论 ...

  4. C++/CLI 托管C++的托管与非托管字符串的相互转换【1】

    Git 源码地址 C++/CLI 托管C++的托管与非托管字符串的相互转换[1] C++/CLI 托管C++的数据类型介绍[2] C++/CLI 托管C++的基本数据类型及函数[3] C++/CLI ...

  5. 托管和非托管_技术和托管新闻综述

    托管和非托管 Welcome to our latest round-up of news from the technology and hosting world. Here's what we' ...

  6. 浅析托管与非托管C++代码(转)

    随着Visual Studio .NET 2003在四月24号的发布,许多开发者开始考虑使用一项被成为托管代码的新技术.但是对于C++开发者来说,可以会遇到一些麻烦.因为C++是比较特殊的. 什么是托 ...

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

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

  8. 超详细解析托管与非托管

    1      DLLImport的使用 using System; using System.Runtime.InteropServices; //命名空间 class Example { //用Dl ...

  9. 托管与非托管的混合编程问题

    (急,先放技术区几天再移动) 写C#应用,需要MDI界面,其中一个子窗体是使用浏览器界面的,单独调试都好好的,使用到MDI中就出问题了,不能打开连接,显示忙信息,没有其他任何响应信息. 现在想通过使用 ...

最新文章

  1. 5G时代,MPLS WAN如何发展?-vecloud服务器
  2. 你不知道的JavaScript错误和调用栈常识
  3. IP、TCP、UDP数据包长度问题
  4. 20170102-文件处理
  5. pushlet单播与多播
  6. 去掉 edittext 长按全选_开封消毒湿巾全选
  7. 理论基础 —— 排序 —— 计数排序
  8. [Note]Linux查看ASCII字符表
  9. 信安教程第二版-第18章网络安全测评技术与标准
  10. 领导再也不会因为模型刷新不出来批评我啦---论IE扩内存(转载)
  11. 搜索的php mysql代码生成器_PHP FOR MYSQL 代码生成助手(根据Mysql里的字段自动生成类文件的)...
  12. APP架构师必看:面对爆发流量如何进行架构调整
  13. 如何成为一名出色的演说者
  14. 利萨茹(Lissajous)曲线动画演示
  15. 我的世界服务器彩虹云,《我的世界》彩虹云跑酷地图存档
  16. re模块compile方法
  17. Gromacs—GMX
  18. BufferedImage
  19. Photoshop学习(二十):画面的浮雕效果
  20. navicat 表合并查询_数据库两个表合并命令

热门文章

  1. 中南大学计算机网课网址,中南大学计算机网课复习要点.doc
  2. 弱电包含在计算机专业,弱电工程包含哪些内容
  3. Web服务及相关领域的基金信息
  4. Mac系统下Python下载安装
  5. 计算机毕业生晚会主持稿,2011年华中师范大学计算机科学系迎新晚会主持稿
  6. 谷歌浏览器(chrome)允许跨域/允许https网站中发送http请求
  7. 智能公交系统电子站牌设计
  8. 计算机科学艺术家,计算机科学的鼻祖,编程界的上帝,视世界的码农当作艺术家...
  9. vb中的msgbox的用法
  10. PC通过IE浏览器对华为S5700交换机进行WEB管理