网站建设进程表,网站建设氺首选金手指12,移动网站开发 王府井,永久免费自助网站在介绍C和winrt与COM组件技术的关系之前#xff0c;有必要介绍一下com组件技术#xff0c;这项技术比较古老#xff0c;但是它一直作为windows的基石存在。COM 是一类独立于平台且面向对象的分布式系统#xff0c;用于创建可交互的二进制软件组件。 COM 技术是 Microsoft O…在介绍C和winrt与COM组件技术的关系之前有必要介绍一下com组件技术这项技术比较古老但是它一直作为windows的基石存在。COM 是一类独立于平台且面向对象的分布式系统用于创建可交互的二进制软件组件。 COM 技术是 Microsoft OLE复合文档和 ActiveX支持 Internet 的组件技术的基础。
注意我们仅仅介绍基础的COM组件技术而不是全面的覆盖这项技术讲述这项技术是一项非常困难的工作所以许多知识点我们只是提及不会深究我个人比较推荐的书是《com组件论》这本书非常值得一看。
COM技术被认为是C进阶的高级技术它从本质上解释了接口和实现但是由于COM编程过于复杂并且COM技术本质上windows使用的技术所以慢慢的它被隐藏到系统深处了。
组件对象模型
Microsoft 组件对象模型 (COM) 是一个独立于平台的面向对象的分布式系统可用于创建可以交互的二进制软件组件。 COM 技术是 Microsoft OLE(复合文档)和 ActiveX(支持 Internet 的组件)以及其他组件的基础技术。
要理解 COM(以及所有基于 COM 的技术)关键是要理解它不是一种面向对象的语言而是一种标准。 COM 也没有指定应用程序的结构语言、结构和实现细节留给应用程序开发人员。 相反COM 指定对象模型和编程要求使 COM 对象(也称为 COM 组件有时简称为对象)能够与其他对象进行交互。 这些对象可以在单个进程中也可以在其他进程中甚至可以在远程计算机上。 它们可以以不同的语言编写并且它们在结构上可能大相径庭这就是为什么 COM 被称为二进制标准的原因在程序转换为二进制计算机代码后应用的标准。
COM 唯一的语言要求是代码是用一种可以创建指针结构并通过指针显式或隐式调用函数的语言生成的。 面向对象的语言(如 C 和 Smalltalk)提供简化 COM 对象的实现的编程机制而 C、Java 和 VBScript 等语言可用于创建和使用 COM 对象。
COM 定义 COM 对象的基本性质。 通常软件对象由一组数据和操作数据的函数组成。 COM 对象是专门通过一组或多组相关函数来访问对象数据的对象。 这些函数集被称为接口接口的函数被称为方法。 此外COM 要求访问接口方法的唯一方法是通过指向接口的指针。
除了指定基本的二进制对象标准外COM 还定义了某些基本接口这些接口提供了所有基于 COM 的技术所共有的功能并提供了所有组件所需的少量功能。 COM 还定义了对象如何在分布式环境中协同工作并添加了安全功能来帮助提供系统和组件完整性。
COM 简介
Microsoft 组件对象模型 (COM) 定义了二进制互操作性标准可利用此标准创建在运行时交互的可重用软件库。 无需将 COM 库编译到应用程序中即可使用 COM 库。 COM 是许多 Microsoft 产品和技术的基础例如 Windows Media Player 和 Windows Server。
COM 定义适用于许多操作系统和硬件平台的二进制标准。 对于网络计算COM 定义了标准线路格式和协议用于在不同硬件平台上运行的对象之间交互。 COM 独立于实现语言这意味着可以使用不同的编程语言如 C 和 .NET Framework 中的编程语言创建 COM 库。
COM 规范提供了启用跨平台软件重用的所有基本概念
组件之间的函数调用的二进制标准用于将函数强类型分组到接口中的预配提供多态性、功能发现和对象生存期跟踪的基接口唯一标识组件及其接口的机制从部署创建组件实例的组件加载程序
COM 有许多部件协同工作从而支持创建从可重用组件生成的应用程序
提供符合 COM 规范的运行时环境的主机系统定义功能协定的接口和实现接口的组件向系统提供组件的服务器和使用组件提供的功能的客户端用于跟踪组件在本地和远程主机上的部署位置的注册表用于找到本地和远程主机上的组件并将服务器连接到客户端的服务控制管理器定义如何在主机文件系统上导航文件内容的结构化存储协议 启用跨主机和平台的代码重用是 COM 的核心。 可重用接口实现命名为组件、组件对象或 COM 对象。 一个组件实现一个或多个 COM 接口。
通过设计库实现的接口可定义自定义 COM 库。 库的使用者无需了解库的部署和实现详细信息即可发现和使用其功能。
对象和接口
COM 对象通过接口公开其功能接口是成员函数的集合。 COM 接口定义组件的预期行为和职责并指定一个强类型协定该协定提供一小组相关操作。 COM 组件之间的所有通信都通过接口进行并且通过组件接口公开组件提供的所有服务。 调用方只能访问接口成员函数。 除非在接口中公开内部状态否则调用方无法使用内部状态。
接口是强类型。 每个接口都有自己的唯一接口标识符名为 IID这样就消除了与人类可读名称可能发生的冲突。 IID 是全局唯一标识符 (GUID)此标识符与开放软件基金会 (OSF) 分布式计算环境 (DCE) 定义的通用唯一 ID (UUID) 相同。 创建新接口时必须为该接口创建新的标识符。 当调用方使用接口时它必须使用唯一标识符。 此显式标识可消除会导致运行时失败的命名冲突从而提高稳健性。
定义新接口时可以使用接口定义语言 (IDL) 创建接口定义。 从此接口定义中Microsoft IDL 编译器会生成标头文件供使用接口的应用程序使用并生成源代码来处理远程过程调用。 Microsoft 提供的 IDL 基于 DCE IDL 的简单扩展这是基于远程过程调用 (RPC) 的分布式计算的行业标准。 IDL 是可方便接口设计人员的工具不是 COM 互操作性的核心。 使用 IDL 时无需为每个编程环境手动创建标头文件。
在 COM 接口中很少使用继承。 COM 仅支持接口继承以重用与基接口关联的协定。 COM 不支持选择性继承因此如果一个接口继承自另一个接口则它包括基接口定义的所有函数。 此外接口仅使用单重继承而不是多重继承从基接口获取函数。
接口实现
不能单独创建 COM 接口的实例。 而是创建实现接口的类实例。 在 C 中COM 接口建模为抽象基类这意味着接口是仅包含纯虚拟成员函数的 C 类。 C 库会从一个或多个接口继承成员函数签名、覆盖每个成员函数并为每个函数提供实现从而实现 COM 对象。
可以使用任何支持函数指针概念的编程语言来实现 COM 接口。 例如在 C 中接口是一个结构其中包含指向函数指针表的指针此结构用于接口中的每个方法。
实现接口时类必须为接口中的每个函数提供实现。 如果类在接口函数中无事可做则实现可以是单个 return 语句。
COM 类可使用唯一的 128 位类 ID (CLSID) 标识该 ID 将类与文件系统中的特定部署相关联对于 Windows 而言这是 DLL 或 EXE。 CLSID 是 GUID这意味着没有其他类具有相同的 CLSID。 使用唯一类标识符可防止类之间发生名称冲突。 例如两个不同的供应商可以编写名为 CStack 的类但两个类都具有唯一的 CLSID因此可避免出现任何冲突。
可以使用 CoCreateGuid 函数或使用在内部调用此函数的 COM 创作工具如 Visual Studio获取新的 CLSID。
IUnknown 接口
所有 COM 接口都继承自 IUnknown 接口。 IUnknown 接口包含基本 COM 操作可实现多态性和用于实例生存期管理。 IUnknown 接口有三个成员函数名为 QueryInterface、AddRef 和 Release。 要实现 IUnknown 接口需要所有 COM 对象。
QueryInterface 成员函数为 COM 提供多态性。 调用 QueryInterface 以在运行时确定 COM 对象是否支持特定接口。 如果 COM 对象实现请求的接口则返回 ppvObject 参数中的接口指针否则返回 NULL。 QueryInterface 成员函数支持在 COM 对象支持的所有接口之间导航。
COM 对象实例的生存期由其引用计数控制。 IUnknown 成员函数 AddRef 和 Release 控制计数。 AddRef 会递增计数而 Release 会递减计数。 当引用计数达到零时Release 成员函数可能会释放实例因为没有调用方在使用它。
客户端/服务器模型
一个 COM 类可实现许多 COM 接口。 实现由调用方与 COM 类实例交互时运行的二进制文件组成。 COM 支持在不同应用程序中使用类包括在不了解特定类的情况下编写的应用程序。 在 Windows 平台上类存在于动态链接库 (DLL) 或其他应用程序 (EXE) 中。
在其主机系统上COM 维护系统上安装的 COM 对象的所有 CLSID 的注册数据库。 注册数据库是每个 CLSID 与存放相应类的 DLL 或 EXE 的位置之间的映射。 只要调用方想要创建 COM 类的实例COM 就会查询此数据库。 调用方只需知道 CLSID 即可请求类的新实例。
COM 对象与其调用方之间的交互建模为客户端/服务器关系。 客户端是从系统请求 COM 对象的调用方而服务器是存放向客户端提供服务的 COM 对象的模块。
COM 客户端是将 CLSID 传递给系统以请求 COM 对象实例的任何调用方。 创建实例的最简单方法是调用 COM 函数 CoCreateInstance。
CoCreateInstance 函数会创建指定 CLSID 的一个实例并返回客户端所请求类型的接口指针。 客户端负责管理实例的生存期方法是在客户端使用完实例后调用其 Release 函数。 若要根据单个 CLSID 创建多个对象请调用 CoGetClassObject 函数。 若要连接到已创建且正在运行的对象请调用 GetActiveObject 函数。
COM 服务器向系统提供 COM 实现。 服务器将 CLSID 与 COM 类相关联存放类的实现实现用于创建类实例的类工厂并可用于卸载服务器。
COM 服务器与提供给系统的 COM 对象不同。
若要启用创建 COM 对象COM 服务器必须提供 IClassFactory 接口的实现。 客户端可以调用 CreateInstance 方法以请求 COM 对象的新实例但通常将此类请求封装在 CoCreateInstance 函数中。
可以将 COM 服务器部署为在运行时加载到客户端进程中的共享库Windows 平台上的 DLL或部署为可执行模块Windows 平台上的 EXE。