COM 类对象和 CLSID

COM 服务器作为 COM 类实现。 COM 类 是在与给定对象交互时在代码中执行的一组接口的实现。 C++ 类和 COM 类之间有一个重要区别:在C++中,类是一种类型,而 COM 类只是对象的定义,并且没有类型,尽管C++程序员可以使用C++类实现它。 COM 旨在允许不同应用程序使用类,包括不了解该特定类存在而编写的应用程序。 因此,给定类型的对象的类代码存在于动态链接库(DLL)或其他可执行应用程序(EXE)中。

每个 COM 类由 CLSID(服务器必须注册的唯一 128 位 GUID)标识。 COM 根据客户端的请求使用此 CLSID 将特定数据与包含实现该类的代码的 DLL 或 EXE 相关联,从而创建对象的实例。

对于同一计算机上的客户端和服务器,服务器的 CLSID 是所有客户端所需的。 在每台计算机上,COM 维护一个数据库(它利用Microsoft Windows 和 Macintosh 平台上的系统注册表)为系统上安装的服务器的所有 CLSID。 这是每个 CLSID 与包含该 CLSID 代码的 DLL 或 EXE 的位置之间的映射。 每当客户端想要创建 COM 类的实例并使用其服务时,COM 就咨询此数据库,因此客户端永远不需要知道计算机上的代码的绝对位置。

对于分布式系统,COM 提供了允许远程服务器注册自身供客户端使用的注册表项。 虽然应用程序只需要知道服务器的 CLSID,因为它们可以依赖注册表来查找服务器,但 COM 允许客户端重写注册表项并指定服务器位置,以充分利用网络。 (请参阅 查找远程对象。)

创建类实例的基本方法是通过 COM 类对象。 这只是一个中间对象,它支持创建给定类的新实例所共有的函数。 用于从 CLSID 创建对象的大多数类对象都支持 IClassFactory 接口,该接口包含重要 CreateInstance 方法。 为要实例化的每个对象类实现 IClassFactory 接口。 (有关实现 IClassFactory的详细信息,请参阅 实现 IClassFactory。)

注意

支持某些其他自定义类工厂接口的服务器不需要专门支持 IClassFactory。 但是,对除 CoGetClassObject(如 CoCreateInstanceEx)以外的激活函数的调用要求服务器支持 IClassFactory

 

当客户端想要创建服务器的对象的实例时,它会在调用 CoGetClassObject时使用所需对象的 CLSID。 (通过某个对象创建帮助程序函数,此调用可以是直接调用或隐式调用。此函数查找与 CLSID 关联的代码,并创建类对象,并提供指向所请求接口的指针。 (CoGetClassObject 采用指定客户端所需接口指针的 riid 参数。

注意

COM 只有一些函数,其中许多是构建的。 其中最重要的一项可能是 CoGetClassObject,它为所有实例创建函数提供底层。

 

使用此指针,调用方可以创建对象的实例,并检索指向对象上请求接口的指针。 这通常是一个初始化接口,用于激活对象(将其置于运行状态),以便客户端可以对它想要的对象执行任何作。 使用 COM 的基本函数时,客户端还必须注意释放所有对象指针。

激活对象实例的另一种机制是通过类名字对象。 类名字对象绑定到为其创建它们的类的类对象。 有关详细信息,请参阅 类名字对象

COM 提供了多个帮助程序函数,可减少创建对象实例的工作。 实例创建帮助程序函数中介绍了这些内容。

通过类对象创建对象