【COM原理和应用】1、COM原理和概述

【我们知道,Directshow整体上是构建在COM之上的,也可以认为是COM在视频、流媒体领域的一种特定的应用和封装。如果只是为了开发High level的directshow应用,COM方面的只是其实并非必须;但如果涉及到filter层的自定义开发,那么研究COM的概念和基本原理是很有必要的。现在开始我们将试图学习COM的内容,以求更深入地理解Directshow的知识。】

1、COM的起源

在计算机软件的初期(无论是软件开发行业的初期,还是一个学生初学编程的阶段),一个应用系统往往就是一个单独的应用程序(举一个比较极端的例子:想十多年前我初学C语言的时候,编程环境还是Turbo C 2.0,所有的声明和实现的代码全部写在一个源文件中,并不会使用.h文件,至于不同的模块分别定义在不同的头文件和源文件中的分布代码更是不知为何物。其实,这种方式最多只适合编写课本上的习题和作业,严格地说根本算不上是“开发工作”)。应用越复杂,开发所需要的时间就越长,难度也就越高。不仅如此,每次更新版本必须将整个工程全部重新编译生成,无法对某一个部分单独进行升级,对操作系统和硬件的变化缺乏适应性。在当前这种操作系统和硬件平台日新月异的环境下,这种模式显然完全不能满足软件开发的需求。

解决这个问题很自然的一个思路就是将一个完成的程序分割成多个保持一定功能独立性的模块,每个模块可以单独进行开发、编译、调试和测试,各个模块之间通过规定好的接口实现协作,共同组成一个完整的应用程序。在软件需要升级时,只需要修改某一个受到影响的模块即可,在保证模块之间接口一致的情况下,其他模块和整个系统的运行不受到影响。通过这种方式,不但节省了新版本软件开发的时间,减少了重新发布的代码量,而且避免了重新编译整个系统可能带来的风险,提高了应用的鲁棒性。

实际上,COM模型就是一种可以实现这种思路的模型。在COM中,各个不同的模块称之为COM组件,在win平台中,每一个组件的实现方式可能是一个dll或者exe文件。组件之间通过COM接口进行连接,组件内部包含COM对象并为对象提供活动空间。一个组件可能包含多个COM对象(实际上,大多数情况下只会包含一个),每一个COM对象可能实现了多个COM接口。应用程序由多个COM组件构成,通过实现不同组件中的不同对象实现整个应用的功能。

2、COM结构

COM模型实际上是一个标准,该标准包括规范和实现两部分:规范部分定义了组件之间的通信机制,该机制无关语言和平台;实现部分是COM库,为COM规范提供了一些核心服务。

(1)对象与接口

现代软件开发的世界是面向对象的世界,COM自然不能免俗。COM中的对象同C++等语言中的对象类似,是一组相关的数据和方法的组合体。某一个对象被定义后,使用该对象的对象通常称之为该对象的客户/用户。

接口通常是一组逻辑相关的函数集合,通常也会被封装成一个类,名称以“I”开头(取自“Interface”)。这个类通常会被定义成抽象类,内部的各个接口函数为纯虚函数,在其派生类中实现。每一个接口通过一个128位的GUID标识。

COM结构的应用在运行过程中某个对象的客户无法看到,也不会关心该对象内部的细节。客户只会通过接口调用对象的服务,即通过GUID获取接口指针,通过接口指针调用某个接口的方法。只要接口不改变(通常情况下也是这么规定的),相应的对象还存在,该接口就可以继续为客户提供服务。

COM结构中的某一个对象使用一个唯一的GUID表示,称之为CLSID。在某个COM组件注册过之后,客户程序就可以在注册表中根据CLSID查找到dll路径等相关信息来创建COM对象,并得到一个指向对象某个接口的指针。进一步,可以通过这个指针获取对象所有的接口指针,这样就可以通过这些指针调用对象的所有服务。所以,对于客户程序而言,一个COM对象实际上就是一组不同的接口。

(2)COM库

COM库包括一些核心代码,是的对象和客户可以通过接口在二进制级进行交互。COM库通常实现与操作系统层而非应用软件层,因此COM库依赖于具体系统,且每个系统只有一个COM库。

3、COM特性

(1)语言无关性:所有面向对象编程语言均可使用,但最适合COM开发的还是C++;

(2)进程透明性:客户程序加载COM组件有两种不同的模式 ,即进程内对象和进程外对象。前者会将COM对象加载到客户进程内部,其特点是效率高,但是组件的不稳定可能会危及客户进程;后者运行在另一进程空间中,包括本地进程和远程进程中,其特点是稳定性好,但是效率略低。如此,组件对象服务程序可以分为以下三种类型:进程内服务程序、本地服务程序和远程服务程序。这三种累心过对于客户程序时透明的,只要依照COM规范,客户程序并不在意其区别。

(3)可重用性:COM的重用性建立在二进制级别(而不像C++的继承派生这类代码级别的重用),因此组件对象的重用意在重用组件对象的行为方式而非具体的实现。对象之间的重用可以采用两种机制:包容和聚合。假设COM对象A重用COM对象2的功能,此时A称之为外部对象,B称之为内部对象。在包容模式下,A完全包含了对象B且实现了对象B的接口,且接口的方法直接调用对象B的实现;在聚合模式下,A不实现B的接口,而是直接将B的接口传递给客户程序。

你可能感兴趣的:(com,directshow)