一、C++作为底层组件的缺点
C++编译模型不支持独立二进制组件的设计。C++的编译模型要求客户必须知道对象的布局结构,从而导致了客户和对象可执行代码之间的二进制耦合关系。通常情况下,二进制耦合对于C++非常有好处,因为这样可以产生非常高效的代码。但这种耦合性使得在不重新编译客户的情况下,类的实现无法被替换。由于二进制耦合关系,以及编译器和连接器的不兼容性,简单的把C++类的定义从DLL中引出来并不能提供合理的二进制组件结构。
兼容性问题源于不同编译器对以下两个方面有不同的考虑方案:1、如何在运行时变现语言的特征;2、在链接时刻如何表达符号名字。
二、COM接口
COM接口保证了应用程序与组件、组件与组件之间的正常通信。组件功能通过虚拟函数表访问。客户机不能直接访问vtable,要通过接口指针访问这些表中的函数指针。COM接口的vtable唯一要求是表的第一个字段应为IUnknown的指针。IUnknown是任何组件变为COM组件必须实现的唯一接口,它是所有接口的大门,这个接口管理由对象支持的所有其它接口。
COM禁止多重接口继承有多个不同理由。一个理由是多重继承得到的C++抽象基类的二进制表示将不再是编译器无关的。另一个理由则是源于COM和DCE RPC之间的紧密关系。限制接口使它只能从一个基接口继承,于是COM接口和DCE RPC接口之间的映射就可以直接进行。
COM清晰地把接口/实现/类看作三个不同的概念。接口是与对象进行通信的抽象协议。实现是支持一个或者多个接口的具体数据类型,它为接口的抽象操作提供精确的语义解释。类是被命名的实现,它代表了具体的、可实例化的类型,其正式名称为COM类或者coclass。
三、激活
把一个对象带入到活动状态的动作被称为对象激活。COM有三种激活模型,把对象带入到内存中,并允许客户调用它的方法。一是客户可以要求COM绑定到给定类的类对象。二是客户也可以要求COM根据CLSID所代表的类创建一个新实例,三是客户还可以要求COM根据对象的永久状态把它带入到活动状态。
四、套间
套间定义了一组对象的逻辑组合,这些对象共享同一组并发性和重入限制。每个com对象都属于某个套间,然而,一个套间可以被多个对象共享。套间主要是为了解除客户与对象的并发性和重入限制之间的关联,COM提供了一个非常规范的抽象概念,它建立起对象与进程线程之间相互关系的模型。MTA开发时要注意对象和数据成员的并发访问,不需要序列化访问,所以不使用消息队列。COM规定,只有运行在对象的套间中的线程能够看到也可以访问到该对象。
从一个套间到另一个套间的控制传递过程被称为方法远程传递(method remoting),这也是COM中跨线程、跨进程以及跨主机通信的基础。COM使用所谓的列集技术(marshal),允许接口指针跨越套间边界传递出去。列集一个接口指针,实际上只是简单的把接口变成可以被传输的字节流,字节流唯一标识了对象和它所拥有的套间。