聚合指的是COM对象转接客户端对某个接口的请求。
某COM对象B并不实现ISomeInterface接口,但是可以通过调用某个内部COM对象A来支持该接口。意思是指,当客户端调用B所支持的接口IOtherInterface查询ISomeInterface时,直接将对象A的ISomeInterface接口指针传出去。
实现聚合的关键是COM对象在被聚合时的QueryInterface的处理。按照COM规范,通过接口查询到的IUnknown接口必须唯一。所以即便B对象不实现ISomeInterface接口,但是调用该接口查询到的IUnknown接口应当跟通过IOtherInterface查询到的一样。但因为实际上ISomeInterface是内部对象A的接口,所以为了符合规范,必须对A被聚合的情况进行特殊处理。
内部对象可以在外部对象初始化时通过CoCreateInstance函数创建,该函数的声明为:
STDAPI CoCreateInstance(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID * ppv
);
其中pUnkOuter指针用于指明该组件被聚合,并将外部对象的IUnknown接口指针传进来。这样,在内部对象进行查询的时候,以及AddRef,Release时,可以先判断外部IUnknown指针是否为空,若不为空,就要通过外部IUnknown指针调用QueryInterface,以及AddRef和Release。