COM接口

3.COM接口

关于接口,想说的很多!

3.1.接口的定义

接口是包含了一组成员函数的数据结构,这组成员函数是组件对象暴露出来的信息,客户程序利用这些函数获得组件对象的服务。

(接口的调用机制)客户程序用一个指向接口数据结构的指针来调用接口成员函数,接口指针又指向另一个指针,这第二个指针指向一组函数,称为接口函数表(可以联想到C++中的虚函数表),接口函数表中每一项为4个字节长的函数指针,每个函数指针与对象的具体实现连接起来。通过这种方式,客户只要获得了接口指针,就可以调用到对象的实际功能。结构如图示:



 

对于一个接口,虚函数表是确定的,成员函数个数和顺序是不变的;对于每个成员函数来说,其参数和返回值类型是确定的。在接口定义中,所有这些信息都必须在二进制级别确定,这样才能实现二进制级别的代码复用,并且只要能支持这样的内存结构的描述的开发语言,就可以定义接口。

3.1.1C语言描述


 

说明:

(1)      每一个接口成员函数的第一个参数为指向IDictionary的指针,这就类似于C++类定义中隐藏的this指针,用来提供当前对象实例的属性信息。

(2)      在接口成员函数中,字符串变量必须用Unicode字符指针,COM规范要求使用Unicode字符,所以在组件程序内部用到了ANSI字符的话,则应该进行两种字符表达的转换。

(3)      接口成员函数的调用习惯也是确定的。在Windows平台上有两种调用习惯:一种是_cdecl调用支持函数可变参数调用(printf),一种是_stdcall,由于大多数的语言都使用了_stdcall调用习惯,COM规范也采用了_stdcal调用习惯。

3.1.2C++语言描述

我们不难发现,COM接口定义中的vtable与class的vtable(类的虚函数表)完全一致,因此用class描述COM接口是最为方便的:

 

在class中隐藏了vtable,每个成员函数隐藏了第一个参数this指针,this指针指向类的实例,下图为类IDictionary的内存结构:

 

3.1.3IDL接口定义语言描述 

 

COM在IDL的基础上,进行扩展形成了COM接口描述语言。接口描述语言提供了一种不依赖于任何语言的借口描述方法,因此,它可以成为组件程序和客户程序之间共同的语言。VC++提供了MIDL可以把IDL接口描述文件编译成C/C++兼容的接口描述头文件。

3.2接口的内存模型

上面我们看到了接口的定义方式,但是看到的只是一些函数描述,并没有看到COM接口与COM对象的关系,我们知道每个成员函数的第一个参数是一个指向接口自身的this指针,可以为我们提供COM对象的信息,但是this指针如何与对象状态信息联系起来呢?

为此,我们还需要定义类来实现已定义的接口,并且类中有相关属性的描述信息。接口IDictionary和字典对象的内存结构如图示: 

 

如果同一个CLSID的类定义了两个字典对象,则显然两个字典对象公用了成员函数,但数据属性不能公用,此时内存结构如图示: 

 

如果两个不同CLSID的类定义了两个字典对象,则内存结构如下图:


 

 

3.3接口的一些特点

二进制特性

接口不变性

继承性(扩展性)

运行过程中的多态性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值