| 网站首页 | 业界新闻 | 技术文章 | 视频教程 | 下载频道 | 程序源码 | 个人空间 | 编程论坛 |
 
| 技术教程首页 | 开发语言 | WEB开发 | .NET技术 | 数据库 | 操作系统 | 网页制作 |
 
 
您现在的位置: 编程中国 >> 技术教程 >> 开发语言 >> VC++ >> VC技术资料 >> 正文
  ►  C/C++ 应用程序路线图
C/C++ 应用程序路线图
作者:Kate Gregory…    阅读人次:……    文章来源:MSDN    发布时间:2007-8-31    网友评论()条
 

适用于:
Microsoft Visual C++
Microsoft.NET 公共语言运行库 (CLR)
C++/CLI 扩展
Microsoft .NET Framework
WinFX

摘要: 本文针对(至少到目前为止)在新的和现有的应用程序中还没有以Microsoft .NET Framework 为目标开发平台的 C++ 程序员。 文中为如何转向 .NET Framework 而且避免抛弃现有代码中的投资提供了一些指导,并阐述了为什么应该考虑转向 .NET Framework ,这不仅适用于新的开发工作,对现有应用程序亦然。

为什么要使用公共语言运行库?

Microsoft 总是支持程序员从他们自己的代码中访问操作系统功能。 在 Windows 的早期,我们从 C 语言程序中使用 Windows API ,进行函数调用(比如 GetMessage(), TranslateMessage(), 等等)以达到目的。 随着时间变迁, Windows 功能开始使用 COM 组件比如 Shell 来公开。 为了充分利用 Windows 完整的功能,程序员学会了 COM 的概念,创建了许多 COM 应用程序。 这种演变仍在继续,如今,为了充分发挥 WinFX 的功能,你的应用程序应该使用公共语言运行库,也称 CLR 了。 WinFX 是一种托管 API ,设计成从为 CLR 编写的托管应用程序中调用,通过 WinFX ,你的应用程序能够利用 Avalon 和 Indigo 这样的新技术的功能。 WinFX 是基于 .NET 对象模型的。

访问操作系统功能当然不是 CLR 的唯一优势: .NET Framework 提供了比 COM 和 DCOM 更佳而且更简单的组件模型。 .NET Framework 中包含的托管代码库所能提供的功能,远远超出了操作系统本身,这使我们能够将精力放在应用程序中专门解决特定问题的部分,而用不着再去处理许多人已经解决过的问题。 同样,可以构建一个基于组件的解决方案,而不需涉及以前与 COM 和 DCOM 部署相关的那些困难。

 

相关语言回顾

这是否意味着你应该重新编写所有应用程序呢? 当然不是。 如果原来的应用程序是用 C++ 编写的,现在不对代码做任何改变就可以针对 CLR 进行编译。 重新编写会带来巨大风险,因为在将程序移植到另一种语言比如 C# 时,可能在能够工作的代码中引入错误。 重新编写和转换代码所能期望的最佳值,也不过是实现与以前同样的功能。 如果想以 CLR 为目标平台根本不需要这样做。 相反,你的时间和精力可以花在使用新的系统功能和扩展应用程序的功能上。

自 .NET Framework, CLR 和 C# 发布以来的几年中,许多开发人员都对 Microsoft 的 C++ 计划感到惊奇。 有些人推测 C# 将取代 C++ ,事实上当然并非如此。 C# 是一种比 C++ 更容易学习的语言,它提供了访问 CLR 功能的途径。 对于已经了解 C++ 的人来说,要访问 CLR 的功能,无需学习其他语言, C++ 具备 C# 中没有的功能,因此转向 C# 实际上将会丧失一些能力。

Microsoft Visual C++ 的每个版本与标准的兼容性都比前一版更好,当前版本 Visual C++ .NET 2003 ,大约与 ISO C++ 标准达到了 98% 兼容。 这一版本中访问 CLR 功能的关键字都以双下划线开始,因此不会干扰与标准的兼容性。 虽然这种方式可行,但是很笨拙,而且不够直观。 Visual C++ 2005 中将包含一个新的 C++ 到 .NET 的绑定,该绑定正在以 C++/CLI 的名称进行标准化。 这一修订包括当前 C++ 标准中没有的关键字,但是同样不会干扰符合标准的 C++ 程序,因为它们遵守 ISO C++ 的标准扩展机制。 C++/CLI 扩展的国际标准正在由 ECMA 制定,最终将提交给 ISO 。 与今天的 C# 一样, C++/CLI 将被标准化,因此 Microsoft 将不会是 C++/CLI 编译器的唯一来源。 Visual C++ 2005 现在已经处于 beta 版,因此我们可以立即探讨这些新的扩展。 在这篇白皮书中,我们将在代码示例中使用新的 C++/CLI 语法。 ( CLI 代表的是公共语言基础结构,是 .NET Framework 的标准化部分,包括 .NET 公共语言运行库。)

理解 .NET 上的 C++

当你编写在 CLR 上运行的代码时,你所编写的就是托管代码。 标准 C++ 代码,也就是能够在任何符合标准的 C++ 编译器上编译的代码,可以编译成非托管(本机)代码或者编译成 MSIL : 只需使用一个编译器开关即可。 指定 /clr 选项,编译器就会生成 MSIL ,一个在 CLR 上运行的程序集。 使你的代码成为托管的就是使用 编译器选项。 不需要使用任何特殊的关键字或者太多改变代码(如果需要改变的话),就能够通过 /clr 选项干净利索地进行编译。

编写了托管代码之后,就可以(如果你愿意)使用 CLR 功能了,比如基类库: 这是能够实现 XML 操作、加密解密、数据访问等等功能的强大的类库。 非托管代码,即没有使用 /clr 选项编译的代码,就无法声明托管类的实例,并按托管代码的方式直接调用它们的方法。 可以通过 .NET Interop 从非托管代码中访问托管代码,该技术能够使 .NET 对象看上去像是一个 COM 组件。 这种方式与将代码编译成托管的,并直接调用托管代码相比,肯定要慢。

无论是否使用基类库(和其他托管库),你仍然可以用 C++ 编写程序,仍然拥有 C++ 赋予你的所有功能和灵活性。 可以使用模板,编写操作符重载,创建内联函数,等等。 编译为 MSIL 并不会阻止你使用任何 C++ 功能。 比如说,多重继承被排除在外不是因为代码编译为 MSIL 了,而只是因为你编写的是托管代码而已。

托管和非托管类型

一个普通的 C++ 类,就是编程语言入门课程中教授的那种,将定义一个非托管类型:

class A
{
private:
   int x;
public:
   A(int xx): x(xx) {}
};

无论是否带 /clr 选项编译代码(托管还是非托管代码),这都是一个非托管类型,也俗称为非托管类或者非托管数据。 这个类的实例可以分配在堆栈中,这也是编程语言入门课程中教授的内容:

A something(3);

它们还可以在本机或者非托管堆中创建:

A* otherthing = new A(4);

程序员然后还必须记住清除非托管堆中的对象,使用 delete 操作符:

delete otherthing;

无论是哪一种方式,都不会涉及垃圾回收器,即使代码编译为 MSIL ,而且应用程序运行在运行库上。

但是你也可能需要编写托管类型(也称托管类或者托管数据)。 这些类型可以从其他程序集中调用,其他运行在运行库上的托管代码,无论其他程序集是用什么语言编写的。 用 C# 、用 Visual Basic .NET 或者用你没有听说过但是碰巧能编译成 MSIL 的语言编写的代码,都可以使用你的托管类型。 这种交互是由运行库托管的,而且在大多数情况下,你的代码和其他程序集所创建的那些类型实例的生存期也是由运行库托管的。

这些托管类型是第一级的 .NET 对象。 用 C++/CLI 创建托管类型,可以采取一种自然的语法,与传统 C++ 区别不大:

ref class R
{
private:
   int x;
public:
   R(int xx): x(xx) {}
};

这个类定义使用了一个空格关键字——仅包含一个空格的关键字。 从技术上说, C++/CLI 中并没有 ref 关键字,而只有 ref class 关键字。 这意味着你可以使用名为 ref 的变量而不会引起冲突。 而且这个类 R 可以被用 C# 或者 Visual Basic .NET 或者其他支持 .NET 的语言编写的代码所使用。 可以用 C++/CLI 编写一个类库,使用你作为一位 C++ 程序员多年形成的技术和技巧,然后将这个库用在根本没有使用 C++ 编写的应用程序中。 它们只需要是运行在 CLR 上的应用程序即可。

依然是 C++

转向 CLR 并不意味着要转向 C# 。 许多 C++ 开发人员在 C# 发布时转向了 C# 。 其原因多种多样: C# 的向导和设计器支持更好,而且管理层经常会支持新语言,仅仅是因为它新,而一些开发人员并没有认识到托管应用程序也能够用 C++ 创建。 但是许多开发人员都拒绝这种转向,甚至某种程度上完全拒绝转向 CLR 。 拒绝的理由中常见的主题是: “我喜欢 C++ 。” C++ 具有其他语言不具备的功能,比如真正的确定性析构和模板。 选择用 C++ 编写托管代码时,你可以获得所有 C++ 的功能和所有 CLR 功能: 可谓鱼与熊掌兼得。

确定性析构

在其他支持 .NET 的语言比如 Visual Basic .NET, C# , 或者 Visual C++ .NET 2003 C++ 托管扩展中,实例的位置取决于要创建的类型。 如果创建的是一个托管类型的实例,它将创建在托管堆中:

Dim o as new R(3)  ' VB.NET
R o = new R(3); // C#
R* o = new R(3); // managed extensions for C++

实例(在所有这些例子中都是 o )使用的内存是由运行库托管的,可以被垃圾回收器清除或者重新组织。

相反,如果你创建的是一个值类型的实例,在所有三种语言中,实例都是在堆栈中创建的:

Dim i As Int32 = 7  ' VB.NET
int i = 7; // C#
int i = 7; // managed extensions for C++

只有在 C++/CLI 中你能够获得自由,自行决定在哪里创建对象,是否想让实例的内存由运行库托管。 你可以在托管堆中创建一个引用类的实例(即前面用 ref class 关键字定义的那个实例),如下:

R^ o = gcnew R(3);  // C++/CLI

如果愿意,可以在堆栈中创建实例:

R os(3);

[1] [2] 下一页

 

 
文章录入:编辑01    责任编辑:编辑01 
  • 上一篇文章:

  • 下一篇文章:

  •  
    相关文章
    原创地带
    24小时热门帖子