摘要
本文的目的是为使用和实行Microsoft的组件对象模型(COM)提供迅捷的参考。读者若想更好的理解什么是COM,以及隐藏在它的设计及体系中的动机,应该阅读组件对象模型的技术说明书(MSDN库,技术说明书)。
规则1:必须实现Iunknown
如果一个对象没有至少实现一个最小程度为IUnknown的接口,那它就不是Microsoft的组件对象模型(COM)。
接口设计规则
接口必须直接或间接地从IUnknown继承。
接口必须有唯一的识别(IID)。
接口是不变的。一旦分配和公布了IID,接口定义的任何因素都不能被改变。
接口的成员函数应该有HRESULT类型的返回值,使远端结构可报告远程过程调用(RPC)错误的情况。
接口成员函数的字符串参数应该是Unicode。
实现 IUnknown
对象的同一性。这要求对任何特定IUnknown接口的给定对象实例的QueryInterface调用返回相同的物理指针变量。这导致了所谓的两个接口的QueryInterface(IID_IUnknown, ...)和结果的比较,以确定它们是否为同一对象(COM对象同一性)。
静态接口的设置。任何经由QueryInterface来访问对象的接口的设置,必须是静态而不是动态的。也就是说,假如一旦QueryInterface获得了一个给定的IID,那么它总是对相同的对象(除非有意想不到情况)调用,假如QueryInterface不能获得一个给定的IID,那么随后对相同IID的对象调用必定会失败。
对象完整性。对于可处理的接口设置,必须有反身性,对称性和过渡性。即给定代码如下:
IA * pA = (some function returning an IA*);
IB * pB = NULL;
HRESULT hr;
hr = pA->QueryInterface(IID_IB,&pB); // line 4
Symmetric: pA->QueryInterface(IID_IA, ...) must succeed (a>>a)
Reflexive: If, in line 4, pB was successfully obtained, then
pB->QueryInterface(IID_IA, ...)
must succeed (a>>b, then b>>a).
Transitive: If, in line 4, pB was successfully obtained, and we do
IC * pC = NULL;
hr = pB->QueryInterface(IID_IC, &pC); //Line 7
and pC is successfully obtained in line 7,then
pA->QueryInterface(IID_IC, ...)
must succeed (a>>b, and b>>c,then a>>c).
最小参考服务大小。我们需要实现AddRef来维护一个服务台,它足够大以便支持给定对象的所有接口的2 31 –1有出色的整体指示服务。一个32-位的无符号整型数满足要求。
Release并不意味着失败。假如客户想知道关于资源已被释放等情况,就必须在调用Release之前使用一些对象接口中的较高的语义。