下载 第17章用C++建立ASP组件 我们已看到用COM服务器组件对于建立一个基于网络的应用程序的重要性,但问题不在 于是否建立它们,而在于用什么语言去创建。一种选择是用C++。 人们对C++有许多不同的看法,保守的C++程序员坚持用其他语言创建COM组件,他们 认为只有真正的程序员使用C++。另一方面,VB程序员认为C++是一种很难掌握和使用的语 言,没有必要增加编程时间和进行艰难的尝试。Java程序员认为他们比C++程序员强,因为 James Gosling(Java的发明者)吸收了许多语言(包括C++)的优点发明了Java,本章和下一章的 目的就是消除对C++的偏见和错误概念 本章集中介绍用C++建立服务器组件,不讲述C++语言,如果想学C++,请参阅 Ivor Horton著的《 Beginning Visual C++6》,Wrox出版,书号为 isbn 1-86100088X 本章的主要内容有 C++简史 使用C++原因 从VB移植到C++。 ATL、STL和MFC介绍 ·建立一个COM组件 ·错误处理与调试 更重要的是应该记住,现在,不只是在用C++建立组件,可以使用 Visual c++中可用的任 何工具,使得建立过程更加容易。先从C++的起源谈起。 17.1C++语言 在决定是否使用C++语言之前,最好是搞清楚这种语言的实质,让我们看一下C++的历史 和现状 17.1.1C++简史 刚开始形成的是C语言,那些想建立更快更有效的代码的程序员非常欣赏C语言,有一位 名叫 Bjarne Stroustrup的人却不满足于仅仅是生产快速代码,他想创建面向对象的C语言编程。 他开始对C语言的内核进行必要的修改,使其能满足面向对象模型的要求。C++从此产生 BJarne Stroustrup是C++的最初设计者和实现者。它自诞生以来,经过开发和扩充已成 种完全成熟的编程语言。现在C++已由ANSI、BSI、DIN、其他几个国家标准机构和ISO定为 标准。ISO标准于1997年11月4日经投票正式通过。 C++标准演变了许多年。C++模板是近几年来对此语言的一种扩展,模板是根据类型参数 来产生函数和类的机制,有时也称模板为“参数化的类型”。使用模板,可以设计一个对许多 类型的数据进行操作的类,而不需要为每个类型的数据建立一个单独的类。标准模板库 ( Standard Tempalte Library,STL)和微软的活动模板库( Active Tempalte Library,ATL)都基于
下载 第17章 用C++建立ASP组件 我们已看到用C O M服务器组件对于建立一个基于网络的应用程序的重要性,但问题不在 于是否建立它们,而在于用什么语言去创建。一种选择是用 C + +。 人们对C + +有许多不同的看法,保守的 C + +程序员坚持用其他语言创建 C O M组件,他们 认为只有真正的程序员使用 C + +。另一方面, V B程序员认为C + +是一种很难掌握和使用的语 言,没有必要增加编程时间和进行艰难的尝试。 J a v a程序员认为他们比 C + +程序员强,因为 James Gosling(Java的发明者)吸收了许多语言 (包括C + + )的优点发明了J a v a,本章和下一章的 目的就是消除对C + +的偏见和错误概念。 本章集中介绍用 C + + 建立服务器组件,不讲述 C + +语言,如果想学 C + +,请参阅 I v o r. H o r t o n著的《Beginning Visual C++6》,Wrox 出版,书号为ISBN 1-861000-88-X。 本章的主要内容有: • C++简史。 • 使用C + +原因。 • 从V B移植到C + +。 • AT L、S T L和M F C介绍。 • 建立一个C O M组件。 • 错误处理与调试。 更重要的是应该记住,现在,不只是在用 C + +建立组件,可以使用Visual C++中可用的任 何工具,使得建立过程更加容易。先从 C + +的起源谈起。 17.1 C++语言 在决定是否使用C + +语言之前,最好是搞清楚这种语言的实质,让我们看一下 C + +的历史 和现状。 17.1.1 C++简史 刚开始形成的是C语言,那些想建立更快更有效的代码的程序员非常欣赏 C语言,有一位 名叫Bjarne Stroustrup的人却不满足于仅仅是生产快速代码,他想创建面向对象的 C语言编程。 他开始对C语言的内核进行必要的修改,使其能满足面向对象模型的要求。 C + +从此产生。 Bjarne Stroustrup是C + +的最初设计者和实现者。它自诞生以来,经过开发和扩充已成一 种完全成熟的编程语言。现在 C + +已由A N S I、B S I、D I N、其他几个国家标准机构和 I S O定为 标准。I S O标准于1 9 9 7年11月4日经投票正式通过。 C + +标准演变了许多年。 C + +模板是近几年来对此语言的一种扩展,模板是根据类型参数 来产生函数和类的机制,有时也称模板为“参数化的类型”。使用模板,可以设计一个对许多 类型的数据进行操作的类,而不需要为每个类型的数据建立一个单独的类。标准模板库 (Standard Tempalte Library,S T L )和微软的活动模板库(Active Tempalte Library,AT L )都基于
516 SP3高级编程 下载 这个C++语言扩展 C++标准可分为两部分,C++语言本身和C++标准库。C++标准库对于Ⅴ isual c++是相当 新的,实际上微软只是在发布 Visual c++5.0时去除了一些“bug”。标准库提供了标准的输 入/输出、字符串、容器(如矢量、列表和映射等)、非数值运算(如排序、搜索和合并等)和对 数值计算的支持。应该说,C/C++包含了相对少的关键字,而且很多最有用的函数都来源于 库,C++标准库实现容器和算法的部分就是STL SIL是数据结构和算法的一个框架,数据结构包括矢量、列表和映射等,算法包括这些数 据结构的查找、拷贝和排序等。1994年7月,ANSI/ISOC++标准委员会投票决定接受STL为 C艹+标准库的一部分,这个建议是根据 Alex Stepanov、 Meng leez和 David musser这三人的编 程和软件库研究提出的。STL的产生是为了满足通用性的设计目标,而不是为了提高性能。 那么微软对C++标准的态度怎什么样?微软运行ⅤC++与Plum-HalC++,想比较得到的 分数在92%和93%之间。为什么不是100%的一个原因是跟踪这个标准并同时建立一个编译器 比较困难,微软也考虑了对现有编码兼容的重要性,有时他们不得不偏离标准以保持这个兼 17.12使用C++的原因 应该有充分的理由使用C++创建服务器组件,而不只是为了给上司一个好印象才使用C++ 如果以前没用过C++,你必须要尽力学习 1.性能 性能有个两方面,算法速度和机器代码效率。一个算法可以定义为数据通过系统的概念 化的路径,它描述一些点,在这些点上,数据能够被操作并可转换产生某个结果。例如, 个算法定义为获取一个字符串,计算字符串中的字符个数,并作为结果返回的过程。算法与 语言是独立的,所以在编程之前必须设计算法,编写一个快速程序的第一个步骤是设计良好 的算法,能以最少的操作步骤得出问题的答案。第二个步是选择语言,这也影响程序的速度 从性能的角度考虑,用汇编语言编写程序是最佳的选择,它是计算机能理解的自然语言 但是,几乎没有人用汇编语言编写完整的程序,因为这样做极其乏味。另一个最佳的选择是C 语言。然而,由VC++提供的所有工具都产生C++,而不是C。使用ⅤC++的向导可以生成大量 的使用代码,而不必人工地编写代码。从编写程序的难易程度和程序的性能综合考虑,C++ 是最佳的选择。 C艹+性能良好,因为它被编译为机器代码。对于 VB Script和Java等语言,代码在运行时由 程序解释,而且每次运行程序时都要将代码转换为机器码,这样做效率比较低,不仅仅是已 编译过的C艹程序运行得较快,而且微软C++编译器已存在多年。这意味着微软的编译器程序 员已经把许多优点集中到编译器上,以致于它能产生非常高效的机器码。因为C++是编译语 言,而且非常自然,比VB更接近机器代码,所以由C++编译器产生的代码一定比ⅤB的编译代 码效率更高。 2.错误处理 个好的程序与一个伟大的程序的区别就是其是否具有良好的错误处理支持。实际上, 如果在实现中首先进行错误处理,而不是在最后才进行,那么整个程序的开发和测试过程会 更加完美。但是,错误处理只能与语言所支持的内容相一致
这个C + +语言扩展。 C + +标准可分为两部分, C + +语言本身和C + +标准库。C + +标准库对于Visual C++是相当 新的,实际上微软只是在发布 Visual C++ 5.0时去除了一些“ b u g”。标准库提供了标准的输 入/输出、字符串、容器 (如矢量、列表和映射等 )、非数值运算(如排序、搜索和合并等 )和对 数值计算的支持。应该说, C/C + +包含了相对少的关键字,而且很多最有用的函数都来源于 库,C + +标准库实现容器和算法的部分就是 S T L。 S T L是数据结构和算法的一个框架,数据结构包括矢量、列表和映射等,算法包括这些数 据结构的查找、拷贝和排序等。 1 9 9 4年7月,A N S I/ISO C++标准委员会投票决定接受 S T L为 C + +标准库的一部分,这个建议是根据 Alex Stepanov、Meng Lee和David Musser这三人的编 程和软件库研究提出的。S T L的产生是为了满足通用性的设计目标,而不是为了提高性能。 那么微软对C + +标准的态度怎什么样?微软运行 V C + +与 Plum-Hall C++,想比较得到的 分数在9 2%和9 3%之间。为什么不是1 0 0%的一个原因是跟踪这个标准并同时建立一个编译器 比较困难,微软也考虑了对现有编码兼容的重要性,有时他们不得不偏离标准以保持这个兼 容性。 17.1.2 使用C + +的原因 应该有充分的理由使用C + +创建服务器组件,而不只是为了给上司一个好印象才使用 C + +。 如果以前没用过C + +,你必须要尽力学习。 1. 性能 性能有个两方面,算法速度和机器代码效率。一个算法可以定义为数据通过系统的概念 化的路径,它描述一些点,在这些点上,数据能够被操作并可转换产生某个结果。例如,一 个算法定义为获取一个字符串,计算字符串中的字符个数,并作为结果返回的过程。算法与 语言是独立的,所以在编程之前必须设计算法,编写一个快速程序的第一个步骤是设计良好 的算法,能以最少的操作步骤得出问题的答案。第二个步是选择语言,这也影响程序的速度。 从性能的角度考虑,用汇编语言编写程序是最佳的选择,它是计算机能理解的自然语言。 但是,几乎没有人用汇编语言编写完整的程序,因为这样做极其乏味。另一个最佳的选择是 C 语言。然而,由V C + +提供的所有工具都产生C + +,而不是C。使用V C + +的向导可以生成大量 的使用代码,而不必人工地编写代码。从编写程序的难易程度和程序的性能综合考虑, C + + 是最佳的选择。 C + +性能良好,因为它被编译为机器代码。对于 VB Script和J a v a等语言,代码在运行时由 程序解释,而且每次运行程序时都要将代码转换为机器码,这样做效率比较低,不仅仅是已 编译过的C + +程序运行得较快,而且微软 C + +编译器已存在多年。这意味着微软的编译器程序 员已经把许多优点集中到编译器上,以致于它能产生非常高效的机器码。因为 C + +是编译语 言,而且非常自然,比 V B更接近机器代码,所以由 C + +编译器产生的代码一定比 V B的编译代 码效率更高。 2. 错误处理 一个好的程序与一个伟大的程序的区别就是其是否具有良好的错误处理支持。实际上, 如果在实现中首先进行错误处理,而不是在最后才进行,那么整个程序的开发和测试过程会 更加完美。但是,错误处理只能与语言所支持的内容相一致。 516计计ASP 3 高级编程 下载
Chinapup.com#InrbCEaerr517 Ⅴ SCript具有基本的错误处理支持功能。在默认情况下,不能捕获Ⅴ SCript中的错误。每 次怀疑产生错误时,要调用 On error resume next功能,并检查Eror对象。 而C+中的错误处理比较好,这是因为有“异常处理”,本章的后面部分将详细介绍。 3.最小的依赖性 正如上面所说,C++是一种编译语言,即C++代码在执行之前已转换为机器码。只要此代 码不依赖于外部的动态链接库(DLL),C艹+就可以在不需要安裝额外程序的情况下移动到运行 同样操作系统的其他机器和微处理器上,而移动Java程序时需要先安装Java运行期库 4.利用现有的代码 由于C和C++已经存在许多年了,现在有许多可利用的代码,你的服务器组件可以使用现 有的C/C++代码或库。例如统计库和到老系统的C接 最大化COM特征 COM与C++很接近,实际上, Don box(COM的权威)在他的《 Essential com》一书的第 章写道:“COM就是更好的C++”。他说明了COM规范是如何从C++语言规律中产生出来的。 通过理解C++,会对COM有更深的理解 某些语言不能利用所有的COM特征,而在C++中,几乎可以使用所有的COM特征 17.13不使用C++的原因 知道什么时候使用C++是重要的,同样,知道什么时候不使用C++也是重要的。想像一下 那些长期维护代码的人,如果他们中没有一些C艹+程序员支持C++,那么开发者们不得不把 光转向另外一些他们熟悉的语言。 改变C++组件时,为了看到这些改变的结果,必须重新编译该组件代码,这会花费很长的 开发时间。C++不能像ASP页面代码那样,只使用记事本,改变代码的一行,重新装载而得到 结果。因此,如果某些工作需要经常变化(如原型),不要用C++ 在C++中,对一些致命的错误不能获得更多的保护,写一个使组件崩溃的代码是很容易的 这是为了提供快速代码而付出的代价,C++不会停下来去检查代码是否按设计运行能否使程 序不崩溃依赖于开发者的技巧。如果在这方面花的时间较少或刚刚学习C++,最好不要使用 C++。等到已经意识到C++中所有容易犯的错误,而且在检测组件之前花了许多时间,才可以 使用C++,如果想很快、很容易地建立一个组件,而且也不考虑该组件的执行速度,那么使 用ⅤB吧! 17.14把ASP技巧转到C++上 学习新东西的最好方法就是利用现有的技巧。对于ASP开发者来说,已经学习了C++所 求的许多技巧,特别是, JScript语法和 Activex或COM的面向对象编程的概念 大部分ASP开发者都用 jScript在浏览器上使用 DHTML。 JScript的语法与C非常相似,所 以,如果懂得 JScript,那么就懂得基本的C语法。当然,只是C艹+语法的子集。C+有许多额 外的语法来支持面向对象编程,这就是我们下一步要做的。 2.面向对象编程 如果你在VB中使用过类(clas9,则对任何COM对象和文档对象模型( Document Object
V B S c r i p t具有基本的错误处理支持功能。在默认情况下,不能捕获 V B S c r i p t中的错误。每 次怀疑产生错误时,要调用 On Error Resume Next功能,并检查E r r o r对象。 而C + +中的错误处理比较好,这是因为有“异常处理”,本章的后面部分将详细介绍。 3. 最小的依赖性 正如上面所说,C + +是一种编译语言,即C + +代码在执行之前已转换为机器码。只要此代 码不依赖于外部的动态链接库 ( D L L ),C + +就可以在不需要安装额外程序的情况下移动到运行 同样操作系统的其他机器和微处理器上,而移动 J a v a程序时需要先安装J a v a运行期库。 4. 利用现有的代码 由于C和C + +已经存在许多年了,现在有许多可利用的代码,你的服务器组件可以使用现 有的C/C + +代码或库。例如统计库和到老系统的 C接口。 5. 最大化C O M特征 C O M与C + +很接近,实际上,Don Box(COM的权威)在他的《Essential COM》一书的第 一章写道:“C O M就是更好的C + +”。他说明了C O M规范是如何从C + +语言规律中产生出来的。 通过理解C + +,会对C O M有更深的理解。 某些语言不能利用所有的C O M特征,而在C + +中,几乎可以使用所有的C O M特征。 17.1.3 不使用C + +的原因 知道什么时候使用C + +是重要的,同样,知道什么时候不使用 C + +也是重要的。想像一下 那些长期维护代码的人,如果他们中没有一些 C + +程序员支持C + +,那么开发者们不得不把眼 光转向另外一些他们熟悉的语言。 改变C + +组件时,为了看到这些改变的结果,必须重新编译该组件代码,这会花费很长的 开发时间。C + +不能像A S P页面代码那样,只使用记事本,改变代码的一行,重新装载而得到 结果。因此,如果某些工作需要经常变化 (如原型),不要用C + +。 在C + +中,对一些致命的错误不能获得更多的保护,写一个使组件崩溃的代码是很容易的。 这是为了提供快速代码而付出的代价, C + +不会停下来去检查代码是否按设计运行能否使程 序不崩溃依赖于开发者的技巧。如果在这方面花的时间较少或刚刚学习 C + +,最好不要使用 C + +。等到已经意识到C + +中所有容易犯的错误,而且在检测组件之前花了许多时间,才可以 使用C + +,如果想很快、很容易地建立一个组件,而且也不考虑该组件的执行速度,那么使 用V B吧! 17.1.4 把A S P技巧转到C + +上 学习新东西的最好方法就是利用现有的技巧。对于 A S P开发者来说,已经学习了 C + +所要 求的许多技巧,特别是,J S c r i p t语法和A c t i v e X或C O M的面向对象编程的概念。 1. JScript 大部分A S P开发者都用J S c r i p t在浏览器上使用 D H T M L。J S c r i p t的语法与C非常相似,所 以,如果懂得J S c r i p t,那么就懂得基本的 C语法。当然,只是 C + +语法的子集。C + +有许多额 外的语法来支持面向对象编程,这就是我们下一步要做的。 2. 面向对象编程 如果你在V B中使用过类 ( c l a s s ),则对任何 C O M对象和文档对象模型 (Document Object 第1 7章 用C + +建立A S P组件计计517 下载
518 ASP3高级编程 下载 Model,DOM)都应熟悉,因为已经有了面向对象编程(OOP)的概念。在前面已经说过,C和 C++的区别是C++支持面向对象编程 17.2VC++库 大量的程序员都尽可能多地利用现有的代码。程序员经常购买那些包装成库的代码,而 且许多成功的公司正是靠生产真正优秀的代码库而发展起来的,例如 Rogue wave Software(www.roguewave.com 当C语言流行时,代码库就是函数库。例如,可以购买一个数学库,该库含有完成微积分 和代数运算的函数。通常,可以在程序代码中使用一个包含文件来指定一个函数库,可以静 态或动态地链接这个函数库 静态链接意味者库代码直接集成到程序中。在这种情况下,程序不依赖于其他文件,但 文件的大小可能很大。动态链接意味着程序有库的版本信息,其代码存放于一个单独的文件 中,这个文件称为动态链接库(DLL)。只有程序运行期间调用DLL中的函数时,才加载DLL到 内存。DLL作为一个独立的实体存在于内存中,可以同时被多个程序访问 出现C+后,函数库转变为类库。两者的区别在于函数库只包含一系列函数,而类库是用 面向对象编程的原理设计的,例如,可以为数据结构做一个类库,该库包括一个链接列表的 类。如果使用一个函数库代替,那么链接列表会独立于操作它的函数。另一方面,使用类库 时,链接列表和操作它的函数存在于同一个文件的同一个类中。然而,正如使用函数库一样, 使用类库涉及到包含文件和链接一个静态库 最近,已经从类库发展到模板库。其原因是¢艹τ编译器现在已经能够处理C++模板。模板 库提供了一系列优于类库的优点。要使用模板库,只要在程序中加入包含文件即可,不用链 接到库,因为所有的库代码已经包含在该包含文件中了。 这听起来不是非常高效,早期确实如此,因为每个包含有模板文件的文件都要得到一个 单独的代码拷贝。因此,编译后的程序会很大。但是,为了适应模板,编译器已经优化,使 得这种方法非常高效。 VC有三个供开发者使用的库:一个类库(MFC),二个模板库(ATL和STL) 17.21微软基础类库 微软基础类库(MFC)是微软为帮助C++开发者而建立的类库,含有支持各种不同功能的许 多类,包括实现复杂的数据结构、操作 Windows和访问数据库等。但是,是否应在服务器组 件中使用MFC?回答是否定的 这很明智的,不要在服务器组件中使用MFC,服务器组件不能访问win32,所以不需要 MFC库,数据库支持最好用ATL实现 ATL支持ADO和 OLE DB,而MFC不支持。STL与MFC相比有更好的数据结构支持。即使 最常用的MFC类,如 CString,在标准C库中也有等价的类。偶尔会使用MFC类,如 CSocket, 但它也可被一种win32AP代替。 MFC是用来建立单独 Windows应用程序的,不是用于轻量的COM组件。只有在与现有的 使用MFC的代码接口时应使用MFC类。其他情况使用ATL和STL类,这样可以使组件更小且 运行得更快
M o d e l,D O M )都应熟悉,因为已经有了面向对象编程 ( O O P )的概念。在前面已经说过, C和 C + +的区别是C + +支持面向对象编程。 17.2 VC++库 大量的程序员都尽可能多地利用现有的代码。程序员经常购买那些包装成库的代码,而 且许多成功的公司正是靠生产真正优秀的代码库而发展起来的,例如 Rogue Wa v e S o f t w a r e ( w w w. r o g u e w a v e . c o m )。 当C语言流行时,代码库就是函数库。例如,可以购买一个数学库,该库含有完成微积分 和代数运算的函数。通常,可以在程序代码中使用一个包含文件来指定一个函数库,可以静 态或动态地链接这个函数库。 静态链接意味者库代码直接集成到程序中。在这种情况下,程序不依赖于其他文件,但 文件的大小可能很大。动态链接意味着程序有库的版本信息,其代码存放于一个单独的文件 中,这个文件称为动态链接库 ( D L L )。只有程序运行期间调用 D L L中的函数时,才加载D L L到 内存。D L L作为一个独立的实体存在于内存中,可以同时被多个程序访问。 出现C + +后,函数库转变为类库。两者的区别在于函数库只包含一系列函数,而类库是用 面向对象编程的原理设计的,例如,可以为数据结构做一个类库,该库包括一个链接列表的 类。如果使用一个函数库代替,那么链接列表会独立于操作它的函数。另一方面,使用类库 时,链接列表和操作它的函数存在于同一个文件的同一个类中。然而,正如使用函数库一样, 使用类库涉及到包含文件和链接一个静态库。 最近,已经从类库发展到模板库。其原因是 C + +编译器现在已经能够处理 C + +模板。模板 库提供了一系列优于类库的优点。要使用模板库,只要在程序中加入包含文件即可,不用链 接到库,因为所有的库代码已经包含在该包含文件中了。 这听起来不是非常高效,早期确实如此,因为每个包含有模板文件的文件都要得到一个 单独的代码拷贝。因此,编译后的程序会很大。但是,为了适应模板,编译器已经优化,使 得这种方法非常高效。 V C有三个供开发者使用的库:一个类库 ( M F C ),二个模板库( AT L和S T L )。 17.2.1 微软基础类库 微软基础类库( M F C )是微软为帮助C + +开发者而建立的类库,含有支持各种不同功能的许 多类,包括实现复杂的数据结构、操作 Wi n d o w s和访问数据库等。但是,是否应在服务器组 件中使用M F C?回答是否定的! 这很明智的,不要在服务器组件中使用 M F C,服务器组件不能访问 Win 3.2,所以不需要 M F C库,数据库支持最好用AT L实现。 AT L支持A D O和OLE DB,而M F C不支持。S T L与M F C相比有更好的数据结构支持。即使 最常用的M F C类,如C S t r i n g,在标准C库中也有等价的类。偶尔会使用 M F C类,如C S o c k e t, 但它也可被一种Win 32 API代替。 M F C是用来建立单独Wi n d o w s应用程序的,不是用于轻量的 C O M组件。只有在与现有的 使用M F C的代码接口时应使用 M F C类。其他情况使用 AT L和S T L类,这样可以使组件更小且 运行得更快。 518计计ASP 3 高级编程 下载
ina-pubcoM m78 mC. E AS 519 下载 17.22活动模板库 你可以判断出活动模板库(ATL)比MFC新,因为ATL中有“ Active”这个词,另一种叫法 是“微软模板库”( Microsoft Templete Library,MTL。 ATL用来快速、简易地创建COM组件,而且只占用较少的内存,组件的关键部分是由 C++模板完成的。实际上,ATL的设计在模板的使用上沿用了STL C++模板提供一种类型安全的方法来实现一般的接口。很幸运,微软提供了一些产生ATL 代码的向导,所以在建立简单组件时,不必了解模板,甚至不用知道 Activex的所有细节 ATL另一个优点是不依靠DLL,就是说在装载应用程序时,不必装载DLL和静态地链接,这 两项会增加对内存空间的需求。 ATL使COM的开发更加容易,ATL同样支持通过 OLE DE消费者和提供者的数据访问,还 有一些特殊的用途,如支持建立微软管理控制台(MMC)插件组件。 与ATL比较,MFC依赖于额外的运行期DLL或静态链接,所以产生了比ATL大而慢的代码。 因此,在建立COM组件时,如果没有用户界面,那么选择ATL比MFC好。 17.23标准模板库 标准模板库(STL)对于VC艹+编程员来说是使用得最不充分的有用工具之一,但它是唯 一个标准的和跨平台的ⅤC++库。 使用STL不多的原因之一是,微软的STL文献难以理解。现在没有为ⅤC++程序 员而编写的STL书藉,由 Musser和 Sauni编写的《 STL Tutorial and Reference guide》 是一本关于STL的好书。 STL对C艹+组件开发很有用,原因是包含了许多数据结构和算法。很多情况下,服务器组 件的用途就是处理数据,STL非常合适这一用途。 微软最初实现SIL标准是在ⅤC++4.2中,但是,这个STL实现做得很差,以致不能使用 些人通过使用HP或SGI提供的STL实现解决这个问题。既然STL是一种ISO/ANSI标准,它 就是跨平台的,只要编译器支持STL所要求的结构就可以。然而,微软更新的STL实现(在 VC++5.0和60中的提供),比以前的STL更稳定、更容易使用 STL是对ATL的完美补充,ATL没有数据结构和算法。而且,STL和ATL有相似的实现方 法,即使用C++模板,所以配合得很好,而且两者都不需要链接额外的动态或静态链接库, 这样就会使组件更小,使它们对DLL的依赖更小。 下面让我们对STL的关键概念做些介绍,在建立服务器组件时要用到这些概念 1.STL遍历器 使用C编程时,一般使用两种方法来遍历数据结构:使用一个下标或递增一个指针,这两 种方法达到相同的效果。但是编写一个通用的算法来处理不同的类型是不可能的,用STL遍 历器能解决这个问题,下面的例子是最好的说明 下面的程序展示了两种标准C的遍历方法,最后是STL的遍历方法。该程序的任务是计算 个字符串中“t”的个数 string mysTlStri const char *myStr cOunt
17.2.2 活动模板库 你可以判断出活动模板库 ( AT L )比M F C新,因为AT L中有“A c t i v e”这个词,另一种叫法 是“微软模板库”(Microsoft Templete Library,M T L )。 AT L用来快速、简易地创建 C O M组件,而且只占用较少的内存,组件的关键部分是由 C + +模板完成的。实际上,AT L的设计在模板的使用上沿用了 S T L。 C + +模板提供一种类型安全的方法来实现一般的接口。很幸运,微软提供了一些产生 AT L 代码的向导,所以在建立简单组件时,不必了解模板,甚至不用知道 A c t i v e X的所有细节。 AT L另一个优点是不依靠 D L L,就是说在装载应用程序时,不必装载 D L L和静态地链接,这 两项会增加对内存空间的需求。 AT L使C O M的开发更加容易,AT L同样支持通过OLE DB消费者和提供者的数据访问,还 有一些特殊的用途,如支持建立微软管理控制台 ( M M C )插件组件。 与AT L比较,M F C依赖于额外的运行期D L L或静态链接,所以产生了比AT L大而慢的代码。 因此,在建立C O M组件时,如果没有用户界面,那么选择 AT L比M F C好。 17.2.3 标准模板库 标准模板库( S T L )对于V C + +编程员来说是使用得最不充分的有用工具之一,但它是唯一 一个标准的和跨平台的V C + +库。 使用S T L不多的原因之一是,微软的 S T L文献难以理解。现在没有为 V C + +程序 员而编写的S T L书藉,由M u s s e r和S a u n i编写的《STL Tutorial and Reference Guide》 是一本关于S T L的好书。 S T L对C + +组件开发很有用,原因是包含了许多数据结构和算法。很多情况下,服务器组 件的用途就是处理数据,S T L非常合适这一用途。 微软最初实现S T L标准是在VC++ 4.2中,但是,这个S T L实现做得很差,以致不能使用。 一些人通过使用H P或S G I提供的S T L实现解决这个问题。既然 S T L是一种I S O/A N S I标准,它 就是跨平台的,只要编译器支持 S T L所要求的结构就可以。然而,微软更新的 S T L实现(在 VC++ 5.0和6 . 0中的提供),比以前的S T L更稳定、更容易使用。 S T L是对AT L的完美补充,AT L没有数据结构和算法。而且, S T L和AT L有相似的实现方 法,即使用 C + +模板,所以配合得很好,而且两者都不需要链接额外的动态或静态链接库, 这样就会使组件更小,使它们对 D L L的依赖更小。 下面让我们对S T L的关键概念做些介绍,在建立服务器组件时要用到这些概念。 1. STL遍历器 使用C编程时,一般使用两种方法来遍历数据结构:使用一个下标或递增一个指针,这两 种方法达到相同的效果。但是编写一个通用的算法来处理不同的类型是不可能的,用 S T L遍 历器能解决这个问题,下面的例子是最好的说明。 下面的程序展示了两种标准 C的遍历方法,最后是 S T L的遍历方法。该程序的任务是计算 一个字符串中“t”的个数。 第1 7章 用C + +建立A S P组件计计519 下载
520A5p3高袋程 Chinapub.com 下载 cringLength mysTLStr myStr mySTLStrc_str(): stringLength w strlen( myStr for int i-0:i< stringLength mystr[主] / Iteration using a pointer.*/ for( const char *myPtr my Str: *myptr i='\0' myPtr++) s Iteration using an iterator. for(string:: iterator iter mySTLStr begin()i iter ! mySTLStr end()i iter++) if(*iter==“t’) 使用遍历器解决了使用指针或下标时出现的问题。指针和下标依赖于数据,这些数据在 内存中相邻存放,而遍历器隐藏数据,使数据结构的使用者不必了解数据存储的顺序。隐藏 数据结构允许创建通用的算法,这种算法能够与各种数据结构一起工作,例如与容器一起工 为了算法的效率,SIL定义了五种遍历器的类:输入、输出、前向、双向和随机访问。算 法针对特定的遍历方法设计,因此具有最优的性能。 遍历器相似于指针,移动到下一条目和前一条目分别使用操作符“++”和“-”,同样, 获得一个条目的值使用操作符“*”。 2.STL映射 个映射就是一个排好序的容器,这里关心的是能够根据存储在条目中的键以尽可能快 的速度检索条目,而不是关心使条目以线性的顺序存储在容器中。 STL排序容器有set、 multiset、map和 multimap。set用于条目集合,map用于一个条目与 另一条目的关联。由于使用双向遍历器,排序容器支持以线性顺序移动数据条目,尽管排序 容器的目的是用于键访问。 个映射容器支持基于单独键的快速数据检索,这个键在映射中是唯一的,映射对于稀 疏数据具有节省大量存储空间和减少许多计算时间的潜力,在后面的叙述中你将看到。键和 值是以pair类型存储的,这个类型有两个成员: first和 second。检索 first返回键,检索 second返 回键的值。映射的遍历器就是par类型的遍历器 在本章后面将看到使用映射的例子。 3.STL矢量 个矢量就是序列容器的一个例子,其他序列容器是 deque和list。它们具有相似的功能, 基本的区别在于性能。例如,除了在 deque的开始处插入和删除的速度比在 vector中快之外 一个 deque与一个 vector没什么区别。不同的问题要用不同的方式来访问数据。矢量能对不同 长度的数据提供快速随机的访问,在此序列的末尾插入和删除时较快,而在其他在地方则比 较慢
使用遍历器解决了使用指针或下标时出现的问题。指针和下标依赖于数据,这些数据在 内存中相邻存放,而遍历器隐藏数据,使数据结构的使用者不必了解数据存储的顺序。隐藏 数据结构允许创建通用的算法,这种算法能够与各种数据结构一起工作,例如与容器一起工 作。 为了算法的效率,S T L定义了五种遍历器的类:输入、输出、前向、双向和随机访问。算 法针对特定的遍历方法设计,因此具有最优的性能。 遍历器相似于指针,移动到下一条目和前一条目分别使用操作符“ + +”和“- -”,同样, 获得一个条目的值使用操作符“ *”。 2. STL映射 一个映射就是一个排好序的容器,这里关心的是能够根据存储在条目中的键以尽可能快 的速度检索条目,而不是关心使条目以线性的顺序存储在容器中。 S T L排序容器有s e t、m u l t i s e t、m a p和m u l t i m a p。s e t用于条目集合, m a p用于一个条目与 另一条目的关联。由于使用双向遍历器,排序容器支持以线性顺序移动数据条目,尽管排序 容器的目的是用于键访问。 一个映射容器支持基于单独键的快速数据检索,这个键在映射中是唯一的,映射对于稀 疏数据具有节省大量存储空间和减少许多计算时间的潜力,在后面的叙述中你将看到。键和 值是以p a i r类型存储的,这个类型有两个成员: f i r s t和s e c o n d。检索f i r s t返回键,检索s e c o n d返 回键的值。映射的遍历器就是 p a i r类型的遍历器。 在本章后面将看到使用映射的例子。 3. STL矢量 一个矢量就是序列容器的一个例子,其他序列容器是 d e q u e和l i s t。它们具有相似的功能, 基本的区别在于性能。例如,除了在 d e q u e的开始处插入和删除的速度比在 v e c t o r中快之外, 一个d e q u e与一个v e c t o r没什么区别。不同的问题要用不同的方式来访问数据。矢量能对不同 长度的数据提供快速随机的访问,在此序列的末尾插入和删除时较快,而在其他在地方则比 较慢。 520计计ASP 3 高级编程 下载
apub. coM Mi7% BC R AS mm 521 4.STL算法 STL算法根据对其操作的数据结构的影响方式和相互作用进行分类。STL算法与其操作的 STL数据结构的接口是STL遍历器。STL遍历器扮演了一个重要角色,因为它限制了算法怎样 访问数据。许多算法接收一个函数作为其接口的一部分,这个函数的参数返回一个布尔值 表示一种情况。用函数参数可以定制算法。 当STL算法允许函数作为参数传递。多数情况下,这些函数完成一个比较,并且返回布 尔值。例如,一个排序算法使用一个函数作为参数来比较两个值,这个函数根据某些准则比 较一个值是否比另一个值小。不同的函数有不同的准则,从而导致数据以不同的顺序排列。 更有趣的是,将一个函数对象(而不是函数)作为传递参数。函数对象可以包含状态,这种 状态可以启用存在于某处的比较规则。使用的比较规则依赖于对象的状态。在本章的后面有 个排序算法的比较函数的例子,以这种方式实现。 5.STL算法的分类 STL算法可分为四大类。非变异序列算法,操作不改变数据结构内容:变异序列算法则改 变数据结构内容:相关排序算法能用于排序、合并和二进制查找等多种算法。最后,STL具 有广义的数值算法,用于计算数据结构中的元素。 ·非变异序列算法:不直接改变其操作的数据结构的元素。通常,它们查找数据结构中的 元素,检査序列元素的等式,计算序列元素的个数。find和 count是非变异序列算法的例 子,fnd算法在数据结构的某个范围中移动,査找第一个等于给定值的遍历器。而 count 算法计算数据结构中等于给定值的元素的个数。 ·变异序列算法:修改其操作的数据结构中的元素。这些算法在容器中拷贝、替换、转换、 删除和循环移动元素。fi算法是这种算法的一个例子,它的功能是把给定值的拷贝填 充到一个序列范围中的所有位置。 ·相关排序算法:排序、合并和查找元素。同样,能够对排好序的序列进行设置操作 merge算法是一个例子,它将两个已排序范围内的元素放到一个范围内,并且结果不发 生重叠。 广义数值算法的例子是 accumulate,这个算法对数据结构内的某一指定范围的值求和。 6.使用算法的遍历器 前面已经讲过,STL定义了五种遍历器的类:输入、输出、前向、双向和随机访问,算法 针对特定的遍历方法设计,以确保优化性能 例如,find算法可以用于在各种数据结构中查找值,算法并不关心容器是一个矢量,还 个列表,还是一个数组。唯一的条件是数据结构必须支持 InputIterator, Inputlterator的设计 确保它支持的操作的工作效率。find算法只需要 Inputlterator支持的操作,因此,find算法能高 效地工作。 些算法要求功能更强的遍历器:如sort需要随机访问遍历器( Random Accesslterator) 提供随机访问是以降低性能为代价的,并影响其他操作,例如在容器中间插入元素的操作。 现在已经你有充分的理论知识,下面建立一个组件。 17.3建立一个C++服务器组件 C++是标准化的计算机语言,不属于任何人,而属于一个标准委员会。STL是支持数据结
4. STL算法 S T L算法根据对其操作的数据结构的影响方式和相互作用进行分类。 S T L算法与其操作的 S T L数据结构的接口是S T L遍历器。S T L遍历器扮演了一个重要角色,因为它限制了算法怎样 访问数据。许多算法接收一个函数作为其接口的一部分,这个函数的参数返回一个布尔值, 表示一种情况。用函数参数可以定制算法。 一些S T L算法允许函数作为参数传递。多数情况下,这些函数完成一个比较,并且返回布 尔值。例如,一个排序算法使用一个函数作为参数来比较两个值,这个函数根据某些准则比 较一个值是否比另一个值小。不同的函数有不同的准则,从而导致数据以不同的顺序排列。 更有趣的是,将一个函数对象 (而不是函数)作为传递参数。函数对象可以包含状态,这种 状态可以启用存在于某处的比较规则。使用的比较规则依赖于对象的状态。在本章的后面有 一个排序算法的比较函数的例子,以这种方式实现。 5. STL算法的分类 S T L算法可分为四大类。非变异序列算法,操作不改变数据结构内容;变异序列算法则改 变数据结构内容;相关排序算法能用于排序、合并和二进制查找等多种算法。最后, S T L具 有广义的数值算法,用于计算数据结构中的元素。 • 非变异序列算法:不直接改变其操作的数据结构的元素。通常,它们查找数据结构中的 元素,检查序列元素的等式,计算序列元素的个数。 f i n d和c o u n t是非变异序列算法的例 子,f i n d算法在数据结构的某个范围中移动,查找第一个等于给定值的遍历器。而 c o u n t 算法计算数据结构中等于给定值的元素的个数。 • 变异序列算法:修改其操作的数据结构中的元素。这些算法在容器中拷贝、替换、转换、 删除和循环移动元素。 f i l l算法是这种算法的一个例子,它的功能是把给定值的拷贝填 充到一个序列范围中的所有位置。 • 相关排序算法:排序、合并和查找元素。同样,能够对排好序的序列进行设置操作, m e rg e算法是一个例子,它将两个已排序范围内的元素放到一个范围内,并且结果不发 生重叠。 广义数值算法的例子是a c c u m u l a t e,这个算法对数据结构内的某一指定范围的值求和。 6. 使用算法的遍历器 前面已经讲过,S T L定义了五种遍历器的类:输入、输出、前向、双向和随机访问,算法 针对特定的遍历方法设计,以确保优化性能。 例如,f i n d算法可以用于在各种数据结构中查找值,算法并不关心容器是一个矢量,还是 一个列表,还是一个数组。唯一的条件是数据结构必须支持 I n p u t I t e r a t o r,I n p u t I t e r a t o r的设计 确保它支持的操作的工作效率。 f i n d算法只需要I n p u t I t e r a t o r支持的操作,因此,f i n d算法能高 效地工作。 一些算法要求功能更强的遍历器:如 s o r t需要随机访问遍历器 ( R a n d o m A c c e s s I t e r a t o r )。 提供随机访问是以降低性能为代价的,并影响其他操作,例如在容器中间插入元素的操作。 现在已经你有充分的理论知识,下面建立一个组件。 17.3 建立一个C + +服务器组件 C + +是标准化的计算机语言,不属于任何人,而属于一个标准委员会。 S T L是支持数据结 第1 7章 用C + +建立A S P组件计计521 下载
522 ASP3高级编程 Chinapub.com 下载 构和算法的C++扩展。AIL是微软拥有和维护的模板库,使得COM编程更容易。综合这些技 术形成了创建COM组件的一种有效方法,这些COM组件用于ASP页面。 下面用所有这些技术创建一个COM对象,你将看到C++60的向导如何提供大量代 因此,可以把注意力集中在解决问题上,而不是担心具体的编程细节 173.1问题 表现数据的最普通方法是表,列代表字段的类型,每一行是一条记录,拥有字段的值。 在文本文件中,表通常由用逗号分开的值( comma-separated values,CSv)组成 我们将要创建的COM组件以CSV数据作为输入,高效地存储它,并提供访问函数去检索 它。这些数据在COM组件中以STL数据结构表示。在以后部分中,我们会看到怎样用STL算 法去处理这些数据。另外,在下一章,将介绍怎样在数据库中存储存这些数据 为了便于说明,假设数据在一个稀疏表中。第一行的字段是列标题,接下来的是一条条 数据记录,记录的每个字段对齐于列标题。逗号隔离字段,换行符(m)隔离行,空的字段用两 个逗号表示,即 表17-1是一个展开的表的例子。导出时,逗号会隔离每一个字段。 表17-1示例表 Keith moon The who rums Jimi hendrix Guitar vocals enny Kravitz Everything Robert plant Led zeppelin 173.2设计 这个组件的设计目的是使数据的存储空间和访问时间最小。由于数据有可能是稀疏的 即许多字段是空的,这就有可能使数据的存储空间最小化。可以通过数值(基于零的索引)访问 数据的行,可以通过字段名访问数据的列。例如,要得到表17-1中 Keith moon的 iNstrument, 可以调用 Get Field(l," Instrument") 完成以上工作的工具是STL的 vector和map数据结构,这些数据结构是容器,就是说,它 们是包含其他对象的一个集合的对象。为了访问集合中的对象,使用STL遍历器 7.33实现 现在你对这个组件的功能已经有了概念,我们将按下面的步骤实现它 创建包含组件的DLL。 ·创建组件 ·增加属性 增加方法, 1.创建DLL和一个组件 选择 ATL COM App Wizard,创建一个新的vC++项目,然后命名为 ASPComponents。使
构和算法的C + +扩展。AT L是微软拥有和维护的模板库,使得 C O M编程更容易。综合这些技 术形成了创建C O M组件的一种有效方法,这些 C O M组件用于A S P页面。 下面用所有这些技术创建一个 C O M对象,你将看到 VC++ 6.0的向导如何提供大量代码, 因此,可以把注意力集中在解决问题上,而不是担心具体的编程细节。 17.3.1 问题 表现数据的最普通方法是表,列代表字段的类型,每一行是一条记录,拥有字段的值。 在文本文件中,表通常由用逗号分开的值 (comma-separated values,C S V )组成。 我们将要创建的 C O M组件以C S V数据作为输入,高效地存储它,并提供访问函数去检索 它。这些数据在 C O M组件中以S T L数据结构表示。在以后部分中,我们会看到怎样用 S T L算 法去处理这些数据。另外,在下一章,将介绍怎样在数据库中存储存这些数据。 为了便于说明,假设数据在一个稀疏表中。第一行的字段是列标题,接下来的是一条条 数据记录,记录的每个字段对齐于列标题。逗号隔离字段,换行符 ( / n )隔离行,空的字段用两 个逗号表示,即“,,”。 表1 7 - 1是一个展开的表的例子。导出时,逗号会隔离每一个字段。 表17-1 示例表 N a m e G r o u p I n s t r u m e n t Jim Morrison The Doors Vo c a l s Keith Moon The Who D r u m s Jimi Hendrix Guitar & Vo c a l s Lenny Kravitz E v e r y t h i n g Robert Plant Led Zeppelin Vo c a l s 17.3.2 设计 这个组件的设计目的是使数据的存储空间和访问时间最小。由于数据有可能是稀疏的, 即许多字段是空的,这就有可能使数据的存储空间最小化。可以通过数值 (基于零的索引)访问 数据的行,可以通过字段名访问数据的列。例如,要得到表 1 7 - 1中Keith Moon的I n s t r u m e n t, 可以调用GetField (1, "Instrument")。 完成以上工作的工具是 S T L的v e c t o r和m a p数据结构,这些数据结构是容器,就是说,它 们是包含其他对象的一个集合的对象。为了访问集合中的对象,使用 S T L遍历器。 17.3.3 实现 现在你对这个组件的功能已经有了概念,我们将按下面的步骤实现它: • 创建包含组件的D L L。 • 创建组件。 • 增加属性。 • 增加方法。 1. 创建D L L和一个组件 选择ATL COM AppWi z a r d,创建一个新的V C + +项目,然后命名为A S P C o m p o n e n t s。使 522计计ASP 3 高级编程 下载
hab的 第7+建立sP件523 用默认的服务器类型(DLL),不选中复选框,如图17-1所示 This wizard creates an ATL project wthout ClassView to specify the type of object you would New Cla. lke to add to C Executable[E正 厂 Support MIS 图17-1 ATL COM App Wizard的界面1 当完成后,这个向导会自动产生一个组件的外壳。这时没有组件存在,只有DLL根据 COM规范所要求的函数存在,可以在 ASPComponents. cpp文件中看到这些函数,但不用关心 文件的细节,也不用改变它。当向DLL中添加组件时,向导会修改该文件 现在将组件放入DLL。在工作区窗口选择 Class View选项卡,右击 ASPComponents Classes, 选择 New atL Object然后再选 Simple object,并且在 Short name框中键入 Tablestorage,如 图17-2所示 ATL Object wizard Pr Names Aitbutes 广CDM hort N Class. ableStorage IT ableStorage H File: IT ableStorageh CPP File Table Storage. cpp Prog ID: onent: Table Storage Cancel 图17-2 ATL COM App Wizard的界面2 除非你打算更深入地研究ATL,否则在 Attributes选项卡保持默认状态,不必改变任何选 项。对所有这些选项的意义的详细描述已超出本书的范围。 Attributes选项卡如图17-3所示。 点击OK后,就有了一个用来工作的对象
用默认的服务器类型( D L L ),不选中复选框,如图1 7 - 1所示。 图17-1 ATL COM AppWi z a r d的界面1 当完成后,这个向导会自动产生一个组件的外壳。这时没有组件存在,只有 D L L根据 C O M规范所要求的函数存在,可以在 A S P C o m p o n e n t s . c p p文件中看到这些函数,但不用关心 文件的细节,也不用改变它。当向 D L L中添加组件时,向导会修改该文件。 现在将组件放入D L L。在工作区窗口选择C l a s s Vi e w选项卡,右击ASPComponents Classes, 选择New ATL Object。然后再选Simple Object,并且在Short Name框中键入Ta b l e s t o r a g e,如 图1 7 - 2所示。 图17-2 ATL COM AppWi z a r d的界面2 除非你打算更深入地研究 AT L,否则在A t t r i b u t e s选项卡保持默认状态,不必改变任何选 项。对所有这些选项的意义的详细描述已超出本书的范围。 A t t r i b u t e s选项卡如图1 7 - 3所示。 点击O K后,就有了一个用来工作的对象。 第1 7章 用C + +建立A S P组件计计523 下载
524A5p2装程 Chinapub.com 下载 ATL Object wiz. 区 COustom CN 厂 Support !SupportEtrorlnfo 厂 Free Threaded Marshal Support Connection Points Cancel 图17-3设置 Attributes选项卡 到目前为止,VC++向导已经完成了所有的工作,如果查看 TableStorage h,你会看到向导 产生的ATL代码。在大多数情况下,不必改变这些代码。实际上,可以只依靠这些代码,不用 了解ATL,继续进行编程。然而,需要对默认的设置做一点改变,使得生成的代码能够编译。 为了减小组件的大小,当 App Wizard创建一个组件时,自动关闭C++的异常处理。因为如 果启用这一功能的话,则需要C运行期库。STL使用异常处理,所以需要启用它。在 Project Settings对话框的CC++选项卡中,下拉 Category框选择C++ Language,确保 Settings for框设 置为 All Configurations,选择 Enable exception handing复选框,如图17-4所示 图17-4启用异常处理 如果用 Release模式编译可能会得到一个链接错误。当编译一个发行版本的ATL 项目时,如果异常处理没有关闭,会出现这样的问题。使用异常处理时,需要C运行 期启动代码:但是在默认方式下, Release模式的ATL项目定义了 ATL MIN CRT符 号,它拒绝启动代码。为了解决这个问题,在C/C++预处理器定义中删除ATL MIN CRT。详细资料请看微软基础知识库中的文章Ql65259
图17-3 设置A t t r i b u t e s选项卡 到目前为止,V C + +向导已经完成了所有的工作,如果查看 Ta b l e S t o r a g e . h,你会看到向导 产生的AT L代码。在大多数情况下,不必改变这些代码。实际上,可以只依靠这些代码,不用 了解AT L,继续进行编程。然而,需要对默认的设置做一点改变,使得生成的代码能够编译。 为了减小组件的大小,当 A p p Wi z a r d创建一个组件时,自动关闭 C + +的异常处理。因为如 果启用这一功能的话,则需要 C运行期库。 S T L使用异常处理,所以需要启用它。在 P r o j e c t S e t t i n g s对话框的C / C + +选项卡中,下拉C a t e g o r y框选择C++ Language,确保Settings for框设 置为All Configurations,选择Enable exception handing复选框,如图1 7 - 4所示。 图17-4 启用异常处理 如果用R e l e a s e模式编译可能会得到一个链接错误。当编译一个发行版本的 AT L 项目时,如果异常处理没有关闭,会出现这样的问题。使用异常处理时,需要 C运行 期启动代码;但是在默认方式下, R e l e a s e模式的AT L项目定义了_ AT L _ M I N _ C RT符 号,它拒绝启动代码。为了解决这个问题,在 C/C + +预处理器定义中删除 _ AT L _ M I N _ C RT。详细资料请看微软基础知识库中的文章 Q 1 6 5 2 5 9。 524计计ASP 3 高级编程 下载