400万+工程师在用

直播中

一文详解COM接口

接口/总线/驱动

784人已加入

描述

如果你了解C#或者Java语言,接口就会是一个非常熟悉的概念。接口是一个对象上一组操作的集合,不涉及任何实现的细节,接口标志着方法和实现的分离。计算机中这种现象叫做解耦(decoupled)。

o4YBAF_1K06ATUhcAAAUmhKl4O0029.png

在C++中,最接近于接口概念的就是纯虚类(purevirtualclass)。纯虚类就是一个仅仅包含纯虚函数的类,除了纯虚函数不含有任何其它的成员变量或者函数,如:

pIYBAF_1K1OAPvBIAAAKIq-uIBw188.png

这个例子来源于一些用来绘图的库中的对象。IDrawable接口定义了绘图中常用的操作,任何支持绘图功能的对象都必须支持该接口。(惯例,接口名称的首字母为“I”),IDrawable接口目前只定义了一个操作:Draw。

所有的接口都是抽象的,代码中不能直接创建一个IDrawable接口的实例对象(C++语法规则不支持纯虚函数对象的创建)。例如,下面的代码是无法编译通过的:

pIYBAF_1K1mAWKoPAAADxyMLPQs978.png

相反的,图形库都会提供一些对象来实现IDrawable所定义的接口。例如,可以实现一个叫做Shape的类或者一个叫做Bitmap的类,C++中使用继承实现这种关系:

pIYBAF_1K2CAP3NXAAAVWieKhTM696.png

Shape和Bitmap类定义了两种不同的对象,二者都支持绘图功能。每个类都继承自IDrawable接口,而对于Draw方法绘制的具体实现细节可以各自不同。

如果程序中使用二者进行绘制,可以使用IDrawable的指针对象来操纵它们,而不是直接使用Shape和Bitmap对象的指针。

o4YBAF_1K2aATvKDAAAKBXfykIs720.png

这有一个循环遍历IDrawable接口指针的列子,在这个数组中,每项成员可能是Shape对象,也可能是Bitmap对象,更可能是一些支持IDrawable接口的其他对象,代码中无需这些不同类型的实现细节,只需要调用它们都支持的共有接口IDrawable就可以绘制我们想要的图像。

pIYBAF_1K22AXYF2AAAMiJjj-_E419.png

COM组件的一个关键点就是调用者永远不需要知道派生类的具体实现细节。换句话说,在你的代码中一般不会声明Shape或者Bitmap类型的变量。所有的操作都是通过它们共有的接口IDrawable来完成。用这种方式,COM组件可以做到接口和实现的完全分离。

你可以随时改变Shape或者Bitmap对象的绘制方法,例如修复一个bug,或者增加一些新的能力,对于调用者来说是透明的,调用者的代码是无需任何修改的。

在C++中,接口使用类或者结构体来实现。

文章中的代码案例只是用来演示说明问题,真正的COM接口定义显然不会这样简单。一般一个COM接口的定义使用一种叫做InterfaceDefinitionLanguage(IDL)——接口定义语言的东西。这个IDL文件将描述具体的接口行为,然后用IDL文件编译器处理,生成一组C++头文件。

o4YBAF_1K3SAKzJDAAAGpby83h8575.png

当你在使用COM组件的时候,一定要记住接口不是对象。它们是一组必须实现的方法集合。一些对象可以实现一样的接口,例如代码中的Shape对象和Bitmap对象。另外一个对象可以实现几个接口,例如,一个图形库可能定义一个名字叫做ISerializable的接口对象,它用来保存和加载图形对象数据(图形的序列化)。现在考虑下面的代码:

pIYBAF_1K3yAd6nrAAAeaoZ2YIE122.png

在例子中,Bitmap类实现了ISerializable接口,程序可以使用该接口保存和加载Bitmap对象。然而Shape类没有实现这个接口,所以它不支持这个功能。下面是例子中的继承关系:

pIYBAF_1K4SASHlhAAASLJUski0781.png

上面的文字只是简单的介绍COM组件的一些概念,目前我们还没有看见过一个真正的COM组件,接下来的内容从每个COM应用都必须做的一件事开始——COM库初始化。
责任编辑人:CC

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉

20万+工程师都在用,免费PCB检查工具

无需安装、支持浏览器和手机在线查看、实时共享

全部0条评论

快来发表一下你的评论吧 !