用VC进行COM面向对象编程.pdf
《用VC进行COM面向对象编程.pdf》由会员分享,可在线阅读,更多相关《用VC进行COM面向对象编程.pdf(10页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、用 VC 进行 COM 面向对象编程学习各种外挂制作技术,马上去百度搜索魔鬼作坊点击第一个站进入、快速成为做挂达人。一、为什么要用 COM软件工程发展到今天,从一开始的结构化编程,到面向对象编程,再到现在的 COM,编程,目标只有一个,就是希望软件能象积方块一样是累起来的,是组装起来的,而不是一点点编出来的。结构化编程是函数块的形式,通过把一个软件划分成许多模块,每个模块完成各自不同的功能,尽量做到高内聚低藕合,这已经是一个很好的开始,我们可以把不同的模块分给不同的人去做,然后合到一块,这已经有了组装的概念了。软件工程的核心就是要模块化,最理想的情况就是 100%内聚 0%藕合。整个软件的发展
2、也都是朝着这个方向走的。结构化编程方式只是一个开始。下一步就出现了面向对象编程,它相对于面向功能的结构化方式是一个巨大的进步。我们知道整个自然界都是由各种各样不同的事物组成的,事物之间存在着复杂的千丝万缕的关系,而正是靠着事物之间的联系、交互作用,我们的世界才是有生命力的才是活动的。我们可以认为在自然界中事物做为一个概念,它是稳定的不变的,而事物之间的联系是多变的、运动的。事物应该是这个世界的本质所在。面向对象的着眼点就是事物,就是这种稳定的概念。每个事物都有其固有的属性,都有其固有的行为,这些都是事物本身所固有的东西,而面向对象的方法就是描述出这种稳定的东西。而面向功能的模块化方法它的着眼点
3、是事物之间的联系,它眼中看不到事物的概念它只注重功能,我们平常在划分模块的时侯有没有想过这个函数与哪些对象有关呢?很少有人这么想,一个函数它实现一种功能,这个功能必定与某些事物想联系,我们没有去掌握事物本身而只考虑事物之间是怎么相互作用而完成一个功能的。说白了,这叫本末倒置,也叫急功近利,因为不是我们智慧不够,只是因为我们没有多想一步。面向功能的结构化方法因为它注意的只是事物之间的联系,而联系是多变的,事物本身可能不会发生大的变化,而联系则是很有可能发生改变的,联系一变,那就是另一个世界了,那就是另一种功能了。如果我们用面向对象的方法,我们就可以以不变应万变,只要事先把事物用类描述好,我们要改
4、变的只是把这些类联系起来方法只是重新使用我们的类库,而面向过程的方法因为它构造的是一个不稳定的世界,所以一点小小的变化也可能导致整个系统都要改变。然而面向对象方法仍然有问题,问题在于重用的方法。搭积木式的软件构造方法的基础是有许许多多各种各样的可重用的部件、模块。我们首先想到的是类库,因为我们用面向对象的方法产生的直接结果就是许多的类。但类库的重用是基于源码的方式,这是它的重大缺陷。首先它限制了编程语言,你的类库总是用一种语言写的吧,那你就不能拿到别的语言里用了。其次你每次都必须重新编译,只有编译了才能与你自己的代码结合在一起生成可执行文件。在开发时这倒没什么,关键在于开发完成后,你的 EXE
5、 都已经生成好了,如果这时侯你的类库提供厂商告诉你他们又做好了一个新的类库,功能更强大速度更快,而你为之心动又想把这新版的类库用到你自己的程序中,那你就必须重新编译、重新调试!这离我们理想的积木式软件构造方法还有一定差距,在我们的设想里希望把一个模块拿出来再换一个新的模块是非常方便的事,可是现在不但要重新编译,还要冒着很大的风险,因为你可能要重新改变你自己的代码。另一种重用方式很自然地就想到了是 DLL 的方式。Windows 里到处是 DLL,它是Windows的基础,但 DLL 也有它自己的缺点。总结一下它至少有四点不足。(1)函数重名问题。DLL里是一个一个的函数,我们通过函数名来调用函
6、数,那如果两个 DLL 里有重名的函数怎么办?(2)各编译器对 C函数的名称修饰不兼容问题。对于 C函数,编译器要根据函数的参数信息为它生成修饰名,DLL 库里存的就是这个修饰名,但是不同的编译器产生修饰的方法不一样,所以你在 VC里编写的 DLL 在 BC 里就可以用不了。不过也可以用 extern C;来强调使用标准的 C 函数特性,关闭修饰功能,但这样也丧失了 C的重载多态性功能。(3)路径问题。放在自己的目录下面,别人的程序就找不到,放在系统目录下,就可能有重名的问题。而真正的组件应该可以放在任何地方甚至可以不在本机,用户根本不需考虑这个问题。(4)DLL 与 EXE 的依赖问题。我们
7、一般都是用隐式连接的方式,就是编程的时侯指明用什么 DLL,这种方式很简单,它在编译时就把 EXE与 DLL 绑在一起了。如果 DLL 发行了一个新版本,我们很有必要重新链接一次,因为 DLL 里面函数的地址可能已经发生了改变。DLL 的缺点就是 COM 的优点。首先我们要先把握住一点,COM 和 DLL一样都是基于二进制的代码重用,所以它不存在类库重用时的问题。另一个关键点是,COM 本身也是 DLL,既使是 ActiveX 控件.ocx 它实际上也是 DLL,所以说 DLL 在还是有重用上有很大的优势,只不过我们通过制订复杂的 COM 协议,通 COM 本身的机制改变了重用的方法,以一种新
8、的方法来利用 DLL,来克服 DLL 本身所固有的缺陷,从而实现更高一级的重用方法。COM 没有重名问题,因为根本不是通过函数名来调用函数,而是通过虚函数表,自然也不会有函数名修饰的问题。路径问题也不复存在,因为是通过查注册表来找组件的,放在什么地方都可以,即使在别的机器上也可以。也不用考虑和 EXE 的依赖关系了,它们二者之间是松散的结合在一起,可以轻松的换上组件的一个新版本,而应用程序混然不觉。二、用 VC 进行 COM 编程,必须要掌握哪些 COM 理论知识我见过很多人学 COM,看完一本书后觉得对 COM 的原理比较了解了,COM 也不过如此,可是就是不知道该怎么编程序,我自己也有这种
9、情况,我经历了这样的阶段走过来的。要学 COM的基本原理,我推荐的书是COM 技术内幕。但仅看这样的书是远远不够的,我们最终的目的是要学会怎么用 COM 去编程序,而不是拼命的研究 COM 本身的机制。所以我个人觉得对 COM的基本原理不需要花大量的时间去追根问底,没有必要,是吃力不讨好的事。其实我们只需要掌握几个关键概念就够了。这里我列出了一些我自己认为是用 VC 编程所必需掌握的几个关键概念。(这里所说的均是用 C 语言条件下的 COM 编程方式)(1)COM 组件实际上是一个 C+类,而接口都是纯虚类。组件从接口派生而来我们可以简单的用纯粹的 C+的语法形式来描述 COM 是个什么东西:
10、class IObjectpublic:virtual Function1(.)=0;virtual Function2(.)=0;.;class MyObject:public IObjectpublic:virtual Function1(.).virtual Function2(.).;看清楚了吗?IObject 就是我们常说的接口,MyObject 就是所谓的 COM 组件。切记切记接口都纯虚类,它所包含的函数都是纯虚函数,而且它没有成员变量。而 COM 组件就是从这些纯虚类继承下来的派生类,它实现了这些虚函数,仅此而已。从上面也可以看出,COM 组件是以C+为基础的,特别重要的是虚函
11、数和多态性的概念,COM 中所有函数都是虚函数,都必须通过虚函数表 VTable 来调用,这一点是无比重要的,必需时刻牢记在心.COM 规范规定任何组件、任何接口都必须从 IUnknown 继承,IUnknown 包含三个函数,分别是QueryInterface、AddRef、Release。这三个函数是无比重要的,而且它们的排列顺序也是不可改变的。QueryInterface用于查询组件实现的其它接口,说白了也就是看看这个组件的父类中还有哪些接口类,AddRef 用于增加引用计数,Release 用于减少引用计数。引用计数也是 COM 中的一个非常重要的概念。大体上简单的说来可以这么理解,C
12、OM 组件是个 DLL,当客户程序要用它时就要把它装到内存里。另一方面,一个组件也不是只给你一个人用的,可能会有很多个程序同时都要用到它。但实际上 DLL 只装载了一次,即内存中只有一个 COM组件,那 COM 组件由谁来释放?由客户程序吗?不可能,因为如果你释放了组件,那别人怎么用,所以只能由 COM 组件自己来负责。所以出现了引用计数的概念,COM 维持一个计数,记录当前有多少人在用它,每多一次调用计数就加一,少一个客户用它就减一,当最后一个客户释放它的时侯,COM 知道已经没有人用它了,它的使用已经结束了,那它就把它自己给释放了。引用计数是 COM 编程里非常容易出错的一个地方,但所幸
13、VC 的各种各种的类库里已经基本上把 AddRef 的调用给隐含了,在我的印象里,我编程的时侯还从来没有调用过 AddRef,我们只需在适当的时侯调用 Release。至少有两个时侯要记住调用 Release,第一个是调用了QueryInterface以后,第二个是调用了任何得到一个接口的指针的函数以后,记住多查 MSDN以确定某个函数内部是否调用了 AddRef,如果是的话那调用 Release 的责任就要归你了。IUnknown 的这三个函数的实现非常规范但也非常烦琐,容易出错,所幸的事我们可能永远也不需要自己来实现它们。IClassFactory 的作用是创建 COM 组件。我们已经知道
14、 COM 组件实际上就是一个类,那我们平常是怎么实例化一个类对象的?是用new命令!很简单吧,COM 组件也一样如此。但是谁来 new 它呢?不可能是客户程序,因为客户程序不可能知道组件的类名字,如果客户知道组件的类名字那组件的可重用性就要打个大大的折扣了,事实上客户程序只不过知道一个代表着组件的 128 位的数字串而已,这个等会再介绍。所以客户无法自己创建组件,而且考虑一下,如果组件是在远程的机器上,你还能 new 出一个对象吗?所以创建组件的责任交给了一个单独的对象,这个对象就是类厂。每个组件都必须有一个与之相关的类厂,这个类厂知道怎么样创建组件,当客户请求一个组件对象的实例时,实际上这个
15、请求交给了类厂,由类厂创建组件实例,然后把实例指针交给客户程序。这个过程在跨进程及远程创建组件时特别有用,因为这时就不是一个简单的 new 操作就可以的了,它必须要经过调度,而这些复杂的操作都交给类厂对象去做了。IClassFactory 最重要的一个函数就是 CreateInstance,顾名思议就是创建组件实例,一般情况下我们不会直接调用它,API 函数都为我们封装好它了,只有某些特殊情况下才会由我们自己来调用它,这也是 VC 编写 COM 组件的好处,使我们有了更多的控制机会,而 VB 给我们这样的机会则是太少太少了。IDispatch 叫做调度接口。它的作用何在呢?这个世上除了 C+还
16、有很多别的语言,比如 VB、VJ、VBScript、JavaScript 等等。可以这么说,如果这世上没有这么多乱七八糟的语言,那就不会有 IDispatch。:-)我们知道 COM 组件是 C+类,是靠虚函数表来调用函数的,对于VC 来说毫无问题,这本来就是针对 C+而设计的,以前 VB 不行,现在 VB 也可以用指针了,也可以通过 VTable 来调用函数了,VJ 也可以,但还是有些语言不行,那就是脚本语言,典型的如VBScript、JavaScript。不行的原因在于它们并不支持指针,连指针都不能用还怎么用多态性啊,还怎么调这些虚函数啊。唉,没办法,也不能置这些脚本语言于不顾吧,现在网页
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 进行 COM 面向 对象 编程
限制150内