XML语言与对象,COM,接口的概念理解

这个问题涉及到微软Windows生态系统中核心技术的历史与原理,详细拆解一下XML、对象、COM和接口之间的关系,以及它们的工作原理和机制。

一.  核心关系总结

简单来说,它们的关系可以概括为:

* 接口:是核心契约,定义了“能做什么”,而不关心“怎么做”。
* COM:是基于接口的一种**二进制级别的对象模型**,它规定了如何创建、使用和销毁实现了这     些接口的对象,并确保跨语言、跨进程的互操作性。
* 对象:是COM的核心,它是一个具体实现了某个或多个COM接口的代码实体(C++类、C#类等)。
* XML:  在这里扮演了两个角色:
    1)   **描述者**:作为一种通用的、平台无关的标记语言,它可以用来**描述**COM对象的接口        定义(例如在TLB、IDL的后续应用中)或COM组件的配置信息。
    2)   **数据载体**:在更广泛的系统交互中,XML可以作为COM对象之间传递的结构化数据。

二.  各部分的工作原理和机制详解

2.1  接口 - 契约与抽象

2.1.1 是什么

接口是一组纯虚函数的集合。它只定义了函数的名称、参数、返回类型,而没有任何实现。在COM中,所有接口都必须从最基础的 `IUnknown` 接口继承。

2.1.2  工作原理

* 抽象与多态:客户端代码通过接口指针来操作对象,它不知道对象的具体实现是什么(是C++写的还是C#写的),它只关心对象是否实现了这个接口。这实现了“面向接口编程,而非面向实现编程”的原则。
* 二进制标准:COM接口在内存中的布局是一个**函数指针表**。这个表的第一个条目指向 `QueryInterface` 方法,第二个指向 `AddRef`,第三个指向 `Release`,后面才是接口自定义的方法。这种确定的布局方式使得任何语言(只要它能理解函数指针表)都可以调用COM对象。

2.1.3 关键机制

* IUnknown接口:所有COM接口的基类,包含三个核心方法:
1)QueryInterface:用于查询对象是否支持某个接口。这是COM实现多态和接口探索的基础。
2)AddRef:增加对象的引用计数。
3)Release:减少对象的引用计数,当计数为0时,对象自我销毁。

2.2  COM - 二进制对象标准

2.2.1  是什么

COM是一套完整的、独立于编程语言和操作系统的**规范**。它定义了组件对象如何被创建、如何在不同模块(甚至不同机器)间交互、如何管理生命周期等。

2.2.2  工作原理

1)创建对象:客户端不直接使用 `new`,而是通过COM库函数(如 `CoCreateInstance`)并提供一个**CLSID**来请求创建对象。
2) 加载DLL/EXE:系统在注册表中查找该CLSID对应的模块路径(DLL或EXE),然后将其加载到内存。
3)获取类厂:调用模块中暴露的特定函数(如 `DllGetClassObject`)来获取一个“类厂”对象。
4)创建实例:通过类厂对象的 `CreateInstance` 方法,创建出最终需要的COM对象,并返回其第一个接口(通常是 `IUnknown`)的指针。
5)通过接口使用:客户端拿到接口指针后,就可以调用其方法。如果需要其他功能,可以通过 `QueryInterface` 请求其他接口。

2.2.3  关键机制

* 全局唯一标识符:使用GUID(如CLSID, IID)来唯一标识每个组件和接口,避免了名称冲突。
* 引用计数:通过 `AddRef` 和 `Release` 自动化管理对象生命周期,防止内存泄漏和悬空指针。
* 列集:当客户端和对象不在同一个公寓时,COM需要将方法调用及其参数“打包”(列集)成一个标准格式,跨边界传递,然后在另一端“解包”(散集)。这实现了跨线程、跨进程的透明通信。
* 注册表:作为“黄页”,存储了CLSID到实际代码路径的映射关系。

2.3  对象 - 具体的实现

2.3.1  是什么

对象是一个具体实现了COM接口的类的实例。例如,一个用C++编写的 `CFileManager` 类,它继承了 `IUnknown` 和 `IFileOperation` 接口,并提供了所有虚函数的具体实现。

2.3.2  工作原理

*   在内存中,它就是一块数据,其第一个成员变量是一个指向虚函数表(vTable)的指针。
*   这个vTable就是按照COM接口规范排列的函数指针数组。

2.4  XML - 结构化的粘合剂

XML与COM/接口的关系和工作机制体现在以下几个方面:

a) 作为接口定义语言 - IDL 与 TLB

虽然COM最初使用微软的**接口定义语言**来精确定义接口,但这些IDL定义最终会被编译成**类型库**。TLB是一种二进制文件,但它描述的信息(接口、方法、参数类型)完全可以用XML来表示。事实上,后来的 `.NET` 程序集元数据就可以通过工具(如 `tlbexp.exe`)导出为XML格式的程序集清单。XML在这里提供了一个更易读、更通用的方式来**描述**COM接口的契约。

b) 作为配置和描述文件

COM+(COM的增强服务)大量使用XML格式的配置文件来存储组件的属性,例如事务要求、安全性、队列等。这些XML文件告诉COM+运行时如何管理这些组件对象。

c) 作为数据交换格式

一个典型的场景是"MSXML":
*   MSXML本身就是一个COM组件库。它提供了一个名为 `IXMLDOMDocument` 的COM接口。
*   开发者通过COM方式创建了一个 `DOMDocument` 对象。
*   然后通过 `IXMLDOMDocument` 接口的方法(如 `load`, `loadXML`, `getElementsByTagName`)来加载、解析和操作XML数据。
*   在这里,**XML是数据内容**,而**COM是访问和操作这些数据的机制**。

三.  一个完整的场景示例:使用MSXML解析XML

假设一个C++程序需要解析一个配置文件 `config.xml`。

3.1  初始化COM

CoInitialize(NULL);

3.2  创建COM对象

    IXMLDOMDocument *pXMLDoc = nullptr;
    HRESULT hr = CoCreateInstance(CLSID_DOMDocument, // CLSID for the XML parser object
                                  NULL,
                                  CLSCTX_INPROC_SERVER,
                                  IID_IXMLDOMDocument, // IID for the interface we want
                                  (void**)&pXMLDoc);
    *   `CoCreateInstance` 根据 `CLSID_DOMDocument` 去注册表找到 `msxml6.dll` 并加载它。
    *   创建 `DOMDocument` 对象。
    *   返回该对象的 `IXMLDOMDocument` 接口指针给 `pXMLDoc`。

3.3  通过接口使用对象

    VARIANT_BOOL success;
    hr = pXMLDoc->load(L"config.xml", &success); // 调用接口方法加载XML文件
    if (SUCCEEDED(hr) && success) {
        // 使用pXMLDoc的其他接口方法,如selectSingleNode, getAttribute等来读取数据
    }

3.4  XML数据流

    *   磁盘上的 `config.xml` 文件是结构化的XML数据。
    *   MSXML组件(COM对象)通过其接口,将这些数据解析成一个树形结构(DOM),并通过          接口暴露给客户端程序。

3.5  释放对象   

    pXMLDoc->Release(); // 减少引用计数,当计数为0时,对象销毁,DLL可能被卸载
    CoUninitialize();

四.  概论总结

| 概念    | 角色                                 | 核心机制                                               |
| :---      | :---                                    | :---                                                         |
| 接口   | 契约,定义了行为规范。 | 虚函数表、IUnknown、QueryInterface |
| COM | 对象模型与运行时规范,规定了如何实现和交互。 | 引用计数、列集、GUID、注册                                                                                                            表、类厂 |
| 对象   | 实现者,是接口的具体代码实体。 | C++/C#类,实现COM接口的虚函数 |
| XML   | 描述者与数据载体,用于描述接口/配置或作为交换的数据。 | 平台无关的标记语言,结构化文本 |

       它们共同构成了一个时代里,实现“软件模块化、复用和跨语言互操作”的强大技术栈。COM解决了二进制层面的互操作问题,而XML解决了数据表示和传输的标准化问题。后来的 .NET 和 Web Service 在很多方面继承并发展了这些思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千江明月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值