COS组件系统理解
1. Cos中的GetIf也就相当于COM中的queryinterface,可以从此cos组件支持的任意接口通过此函数获取其它支持接口的指针。
2. pOuter指针是用来做com中的aggregation用的,比如annimal的pOuter指针指向kolaa对象,使Ianimal接口可以查询到Ikoala接口。
3. 接口原则上是不能有变量数据的,如果要实现每个接口实例要有自己的变量而且不暴露给客户,例
暴露给用户的ex.h
INEW
{
…
GetI();
SetI();
};
内部的.h
INEWIn
{
…
GetI();
SetI();
Int I;
};
用户使用INEW但在内部 转换成 INEWIn操作;inside ole第二章 ENUMRECT例子多用了一个vtbl结构体隔离接口和实现相比上一方法更好点,但这种方法如果用c语言的client使用此组件,则取得组件接口指针后要PIntface->vtbl->func(),这样调用,c++的client则直接PIntface->func()(COM中可以,cos不行见8)。
4. 每个接口有计数,cos组件本身也有计数。
5. COM中的queryinterface实际上是用把this指针强制类型static_cast转换成其他接口的指针来实现的,而COS里更简单(c语言),每个接口实例都是一个全局的变量,通过匹配接口标志就返回全局变量的指针就行。
6.在C++COM中,实现是继承接口的,在createinst时只实例化实现,而在c语言中,vtbl结构体全是函数指针,接口包含vtbl的指针,实现是另一个结构体包含了vtbl的指针并且有变量,实现被实例化,而vtbl结构体被置为全局变量,详见insideole 第二章ENUMRECT例子程序,cos其没有vtbl的结构体,而是实现的结构体继承了接口结构体(IGet,其实IGet严格意义上不是一个接口,其中有ref变量,为了方便使用),cos这样干违背了com的二进制规范吗??有什么影响呢???待进一步理解com。
7. 引用计数
规则:全局变量:对于保存在全局变量中的接口指针,在将其传递给另外一个函数前,必须调用其addref,由于此变量是全局性的,应此任何函数都可以通过调用其release来终止其生命,对于保存在成员变量中的接口指针,也应这样,因为对于所有成员函数来说,他是全局的。(适用于cos)
8.关于COS与COM的不同之处:COS编出来的实际上是一个BIN(相当于EXE)是可执行文件,而COM编出来的是一个DLL不是可执行的,com的c组件和c++组件保持二进制兼容就可以直接互调,而cos不行:cos编出来的是个bin,这个bin在头上的固定位置有几个固定的接口,另外的一个客户程序要load这个bin,load程序就去查bin头的这几个接口,这几个接口负责解析整个bin提供出来的功能接口,这样load程序就不用自己去遵循某种协议去自己搜索bin的功能接口,所以在编程时c程序做成跟c++保持二进制兼容的在cos里没用,一个cos的c++程序调用load去加载bin,c++程序的load是不去解析bin的,而是bin自己的appentry去解析自己的bin的,所以c++程序也看不到c程序的二进制兼容的结构,只有它自己的bin的appentry看得到。
当时cos设计时有两种选择:1.就是现在的设计思路;2.不把cos编成bin而是编成类似于dll的ELF格式,这样由比如说c++的客户程序去加载此cos,然后使用(跟COM一样),c++客户程序去加载时,客户的load程序就要去解析elf格式,由于elf格式有很多头信息,解析比较麻烦,所以load要能解析elf,才能让客户看到c的兼容二进制功能接口,这样比第一种复杂,在嵌入式环境里也很复杂。