Delphi提供了向导和类,使基于Microsoft的组件对象模型(COM)的应用程序易于实现。使用这些向导,您可以创建基于COM的类和组件以在应用程序中使用,也可以创建实现COM对象、自动化服务器(包括Active Server对象)、ActiveX控件或ActiveForms的功能齐全的COM客户端和服务器。
一、COM技术概述
COM是一种独立于语言的软件组件模型,它支持软件组件和在Windows平台上运行的应用程序之间的交互。COM最重要的方面是,它通过明确定义的接口实现了组件之间、应用程序之间以及客户端和服务器之间的通信。接口为客户端提供了一种在运行时询问COM组件支持哪些功能的方法。要为组件提供其他功能,只需为这些功能添加一个额外的接口。
应用程序可以使用称为分布式COM(DCOM)的机制访问与应用程序位于同一台计算机上的COM组件的接口,也可以访问网络上另一台计算机的COM组件接口。
COM既是一种规范,也是一种实现。COM规范定义了如何创建对象以及它们如何相互通信。根据此规范,COM对象可以用不同的语言编写,在不同的进程空间和不同的平台上运行。只要对象符合书面规范,它们就可以通信。这允许您将遗留代码作为组件与用面向对象语言实现的新组件集成。
COM实现内置于Win32子系统中,该子系统提供了许多支持规范的核心服务。COM库包含一组定义COM对象核心功能的标准接口,以及一小组用于创建和管理COM对象的API函数。
当您在应用程序中使用Delphi向导和VCL对象时,您正在使用Delphi对COM规范的实现。此外,Delphi为COM服务提供了一些包装器,用于它不直接实现的功能(如Active Documents)。您可以在ComObj单元中找到这些包装器,在AxCtrls单元中找到API定义。
注意:Delphi接口和语言遵循COM规范。Delphi使用一组称为Delphi ActiveX框架(DAX)的类来实现符合COM规范的对象。这些类位于AxCtrls、OleCtrls和OleServer单元中。此外,COM API的Delphi接口在ActiveX.pas和ComSvcs.pas中。
二、COM接口
COM客户端通过COM接口与对象通信。接口是一组逻辑上或语义上相关的例程,它们提供服务提供者(服务器对象)与其客户端之间的通信。
例如,每一个COM对象都必须实现基本接口,即IUnKnow。在IUnKnow接口中通过一个名为QueryInterface的例程,客户端可以请求服务器实现的其他接口。
对象可以有多个接口,每个接口实现一个功能。接口提供了一种告诉客户端它提供什么服务的方法,而不提供对象如何或在何处提供此服务的实现细节。
COM接口的关键方面如下:
- 一旦发布,接口就不会改变。您可以依靠接口来提供一组特定的功能。附加功能由附加接口提供。
- 按照惯例,COM接口标识符以大写字母I和定义接口的符号名称开头,如IMalloc或IPersist。
- 接口保证具有唯一标识,称为全局唯一标识符(GUID),它是一个128位随机生成的数字。接口GUID称为接口标识符(IID)。这消除了产品不同版本或不同产品之间的命名冲突。
- 接口与语言无关。您可以使用任何语言来实现COM接口,只要该语言支持指针结构,并且可以通过指针显式或隐式调用函数。
- 接口本身不是对象,它们提供了一种访问对象的方法。因此,客户端不直接访问数据,而是通过接口指针访问数据。Windows 2000添加了另一个间接层,称为拦截器,通过它提供COM+功能,如实时激活和对象池。
- 接口总是继承自基础接口,即IUnKnow。
- COM可以通过代理重定向接口,使接口方法调用能够在线程、进程和网络机器之间调用,所有这些都不会让客户端或服务器对象知道重定向。
三、IUnknown 接口
所有 COM 对象必须支持基本接口,称为 IUnknown,它是基接口类型 IInterface 的类型定义。IUnknown 包含以下例程:
- QueryInterface:提供指向对象支持的其他接口的指针。
- AddRef 和 Release:简单的引用计数方法,用于跟踪对象的生命周期,以便在客户端不再需要其服务时,对象可以删除自己。
客户端通过 IUnknown 方法 QueryInterface 获取对其他接口的指针。QueryInterface 知道服务器对象中的每个接口,并可以给客户端提供所请求接口的指针。当接收到对一个接口的指针时,客户端可以放心地调用该接口的任何方法。
对象通过 IUnknown 方法 AddRef 和 Release 跟踪自己的生命周期,这些方法是简单的引用计数方法。只要对象的引用计数不为零,该对象就会保留在内存中。一旦引用计数达到零,接口实现可以安全地处理底层对象。
四、COM 接口指针
接口指针是指向对象实例的指针,该指针又指向接口中每个方法的实现。通过指向这些方法的指针数组访问实现,该数组称为虚表(vtable)。虚表类似于 Delphi 中支持虚函数的机制。由于这种相似性,编译器可以以与解析对 Delphi 类的方法调用相同的方式解析对接口方法的调用。
虚表在对象类的所有实例之间共享,因此对于每个对象实例,对象代码分配一个包含其私有数据的第二个结构。客户端的接口指针因此是指向虚表指针的指针。
在 Windows 2000 及后续版本的 Windows 中,当一个对象在 COM+ 下运行时,接口指针和虚表指针之间提供了另一个间接层。可供客户端使用的接口指针指向一个拦截器,而拦截器又指向虚表。这允许 COM+ 提供例如即时激活的服务,其中服务器可以以对客户端不透明的方式动态停用和重新激活。为了实现这一点,COM+ 保证拦截器的行为就像普通的虚表指针一样。
五、COM 服务器
COM 服务器是一个应用程序或库,它为客户端应用程序或库提供服务。COM 服务器由一个或多个 COM 对象组成,其中 COM 对象是一组属性和方法。
客户端不需要知道 COM 对象是如何执行其服务的;对象的实现仍然是隐藏的。对象通过其接口提供其服务,如前所述。
此外,客户端也不需要知道 COM 对象的位置。COM 提供了透明的访问,不论对象的位置如何。
当客户端请求 COM 对象的服务时,客户端向 COM 传递一个类标识符 (CLSID)。CLSID 只是一个标识 COM 对象的 GUID。COM 使用这个在系统注册表中注册的 CLSID 来定位适当的服务器实现。一旦找到服务器,COM 就会将代码加载到内存中,并让服务器为客户端创建一个对象实例。这个过程是通过一个特殊的对象称为类工厂(基于接口)间接处理的,该对象按需创建对象的实例。
作为最低要求,COM 服务器必须执行以下操作:
- 在系统注册表中注册条目,将服务器模块与类标识符(CLSID)关联。
- 实现一个类工厂对象,该对象创建特定 CLSID 的另一个对象。
- 将类工厂暴露给 COM。
- 提供一种卸载机制,通过该机制可以将未为客户端服务的服务器从内存中移除。
六、COM 客户端
COM 客户端是利用由另一个应用程序或库实现的 COM 对象的应用程序。最常见的类型是自动化控制器,它们控制自动化服务器,以及托管 ActiveX 控件的 ActiveX 容器。
COM 客户端有两种类型:控制器和容器。控制器启动服务器并通过其接口与之交互。它们从 COM 对象请求服务或作为单独的进程驱动它。容器托管出现在容器用户界面的视觉控件或对象。它们使用预定义接口与服务器对象协商显示问题。通过 DCOM 不可能建立容器关系;例如,出现在容器用户界面中的视觉控件必须本地可用。这是因为控件需要自我绘制,这就要求它们能够访问本地 GDI 资源。
编写这两种类型 COM 客户端的任务非常相似:客户端应用程序获取服务器对象的接口,并使用其属性和方法。Delphi 通过让您将类型库或 ActiveX 控件导入组件封装器,使您更容易开发 COM 客户端,以便服务器对象看起来像其他 VCL 组件。Delphi 允许您在客户端的组件中封装服务器 CoClass,您甚至可以将其安装在组件调色板上。此类组件封装器的示例出现在组件调色板的两个页面上,示例 ActiveX 封装器出现在 ActiveX 页面上,而示例自动化对象出现在服务器页面上。
即使您不选择将服务器对象封装在组件封装器中并将其安装在组件调色板上,您仍然必须使其接口定义可用于您的应用程序。为此,您可以导入服务器的类型信息。
客户端始终可以查询 COM 对象的接口,以确定其能够提供的功能。所有 COM 对象都允许客户端请求已知接口。此外,如果服务器支持 IDispatch 接口,客户端可以查询服务器以获取该接口支持的方法的信息。服务器对象对客户端使用其对象没有期望。同样,客户端无需知道对象是如何提供服务的,它们仅依赖服务器对象提供其接口中描述的服务。
七、COM 扩展
随着COM的发展,它已经扩展到基本COM服务之外。COM是其他技术的基础,例如自动化、ActiveX控件、活动文档和活动目录。此外,在大型分布式环境中工作时,您可以创建事务性COM对象。在Windows 2000之前,这些对象并不是COM的架构部分,而是在Microsoft事务服务器(MTS)环境中运行。从Windows 2000开始,这种支持已集成到COM+中。Delphi提供向导,以便轻松实现使用上述技术的应用程序。
1. 自动化服务器
自动化是指应用程序能够以编程方式控制另一个应用程序中的对象的能力,例如可以同时操作多个应用程序的宏。被操控的服务器对象称为自动化对象,而自动化对象的客户端称为自动化控制器。自动化可以用于进程内、本地和远程服务器。
自动化有两个主要定义:
- 自动化对象定义了一组属性和命令,并通过类型描述来描述它们的能力。为了做到这一点,它必须能够提供有关其接口、接口方法及这些方法参数的信息。通常,这些信息可以在类型库中找到。自动化服务器也可以在通过其IDispatch接口查询时动态生成类型信息。
- 自动化对象使其方法可供其他应用程序使用。为此,它们实现了IDispatch接口。通过该接口,一个对象可以公开其所有方法和属性。通过该接口的主要方法,可以在通过类型信息识别后调用对象的方法。
开发人员通常使用自动化来创建和使用可以在任何进程空间中运行的非视觉 OLE 对象,因为自动化 IDispatch 接口自动化了调用过程。然而,自动化确实限制了可以使用的类型。
2. ActiveX 控件
Delphi 向导使您能够轻松创建 ActiveX 控件。ActiveX 是一种技术,允许 COM 组件,特别是控件,更加紧凑和高效。这对于旨在用于 Intranet 应用程序的控件尤其必要,因为这些控件在使用之前需要由客户端下载。
ActiveX 控件是仅作为进程内服务器运行的视觉控件,可以插入到 ActiveX 控件容器应用程序中。它们本身并不是完整的应用程序,但可以被视为已经编写的 OLE 控件,可以在各种应用程序中重用。ActiveX 控件具有可见的用户界面,并依赖预定义的接口与其主机容器协商输入/输出和显示问题。
ActiveX 控件利用自动化来公开其属性、方法和事件。ActiveX 控件的特性包括能够触发事件、绑定数据源以及支持许可。
ActiveX 控件的一种用途是在网页上作为交互对象。因此,ActiveX 是一个旨在针对万维网交互内容的标准,包括使用 ActiveX 文档通过 Web 浏览器查看非 HTML 文档。有关 ActiveX 技术的更多信息,请参阅 Microsoft ActiveX 网站。
3. Active 文档
主动文档(以前称为OLE文档)是一组支持链接和嵌入、拖放和视觉编辑的COM服务。主动文档可以无缝地整合不同格式的数据或对象,例如音频片段、电子表格、文本和位图。
与ActiveX控件不同,主动文档不限于进程内服务器;它们可以在跨进程应用程序中使用。
与几乎从不可视的自动化对象不同,主动文档对象可以在另一个应用程序中可视化活动。因此,主动文档对象与两种类型的数据相关联:表示数据,用于在显示器或输出设备上可视化显示对象,以及原生数据,用于编辑对象。
主动文档对象可以是文档容器或文档服务器。虽然Delphi没有提供创建主动文档的自动向导,但您可以使用VCL类Vcl.OleCtnrs.TOleContainer来支持现有主动文档的链接和嵌入。
您还可以将Vcl.OleCtnrs.TOleContainer用作主动文档容器的基础。要为主动文档服务器创建对象,请使用COM对象向导并根据对象需要支持的服务添加相应的接口。有关创建和使用主动文档服务器的更多信息,请访问Microsoft ActiveX网站。
注意:
虽然活动文档的规范内置支持在跨进程应用程序中的编组,但活动文档不在远程服务器上运行,因为它们使用特定于给定机器上系统的类型,如窗口句柄、菜单句柄等。
4. 事务对象(Transactional Objects)
delphi使用“事务对象”一词来指代利用微软事务服务器(MTS)(适用于Windows 2000之前的版本)或COM+(适用于Windows 2000及更高版本)提供的事务服务、安全性和资源管理的对象。这些对象旨在在大型分布式环境中工作。
事务服务提供了健壮性,以确保活动始终要么完成,要么回滚。服务器从不部分完成某项活动。安全服务允许您向不同类别的客户端公开不同级别的支持。资源管理允许对象通过资源池化或仅在使用时保持对象处于活动状态来处理更多客户端。为了使系统能够提供这些服务,对象必须实现IObjectControl接口。要访问这些服务,事务对象使用一个名为IObjectContext的接口,该接口由MTS或COM+为它们创建。
在MTS下,服务器对象必须构建为DLL库,然后安装在MTS运行时环境中。也就是说,服务器对象是一个在MTS运行时进程空间中运行的进程内服务器。在COM+下,这个限制不适用,因为所有COM调用都通过拦截器路由。对于客户端,MTS和COM+之间的差异是透明的。
MTS或COM+服务器将运行在同一进程空间中的事务对象分组。在MTS下,这个组称为MTS包,而在COM+下则称为COM+应用程序。单台机器可以运行几个不同的MTS包(或COM+应用程序),每个包运行在一个独立的进程空间中。
对于客户端,事务对象可能看起来像任何其他COM服务器对象。除非客户端自己发起事务,否则不需要了解事务、安全性或即时激活。
MTS和COM+都提供了一个单独的工具来管理事务对象。该工具允许您将对象配置为包或COM+应用程序,查看计算机上安装的包或COM+应用程序,查看或更改包含对象的属性,监控和管理事务,使对象可供客户端使用等。在MTS下,该工具是MTS资源管理器。在COM+下,它是COM+组件管理器。
5.类型库(Type Libraries)
类型库提供了一种获取比对象接口上可以确定的更多类型信息的方法。类型库中包含的类型信息提供了关于对象及其接口所需的信息,例如在特定对象(给定 CLSID)上存在哪些接口、每个接口上存在哪些成员函数,以及这些函数需要什么参数。
您可以通过查询正在运行的对象实例或通过加载和读取类型库来获取类型信息。通过这些信息,您可以实现一个客户端,以使用所需的对象,具体知道您需要哪些成员函数,以及该向这些成员函数传递什么。
自动化服务器、ActiveX 控件和事务对象的客户端期望可以获得类型信息。Delphi 的所有向导会自动生成类型库,尽管 COM 对象向导使其成为可选。您可以使用类型库编辑器查看或编辑此类型信息。

3964

被折叠的 条评论
为什么被折叠?



