COM开发指南(1)—COM技术概述

1 COM技术体系

1.1 COM的架构

  COM(Component Object Model,组件对象模型) 是由微软公司制定的一种Windows平台下的软件模块复用技术。借助于COM技术,用户可以编写一些具有特定接口的软件模块(称为COM组件 ),它们可以以dll或exe的形式注册到Windows系统中来对外公开自己,其它的应用程序则可以借助于Windows提供的API来调用这些组件,从而在整个系统范围内实现了软件模块的复用。
  COM技术是基于C/S架构的,其如图1-1所示。架构中的服务端就是注册到Windows系统的COM组件,它们是为其他应用程序提供服务的。架构中的客户端就是调用COM组件的应用程序,它可以是dll,可以是exe,可以是C++编写的,也可以是Java编写的,总而言之COM客户端可以是任意一种可运行在Windows平台的可执行程序,它们通过COM组件提供的服务来实现自身的功能。架构中的通信协议就是COM客户端与COM组件之间的通信方法(也即如何开发COM服务端,以及COM客户端如何调用COM组件),这其中主要包括COM组件的开发规范以及一组包含在Windows SDK中的COM API函数(COM库函数)。
在这里插入图片描述

1.2 COM DLL

  大多数COM组件在开发完成后都会被编译成DLL的形式注册在操作系统的注册表中(也有的编译成exe),然后COM客户端即可通过一组特定的函数从注册表中搜索该COM DLL的路径,并将其加载到内存中调用它。一个COM DLL通常就称为一个COM组件(实际上这种说法是笼统的,因为可以在COM DLL中定义多个注册到注册表的COM组件,只不过绝大多数时候一个COM DLL只会导出一个COM组件,因此通常笼统的将一个COM DLL称作为一个COM组件)。一个COM组件可以包含多个可被COM客户端调用的类,这些类都是继承自一组标准COM接口的类(这组接口定义在Windows SDK中,详见“二 COM接口类”),并且这些类通常会相互调用,相互依赖而形成一个树形结构的类关系(这种关系是通过COM技术的包容和聚合实现的,详见“三 COM组件类”)。
一个COM DLL中包含的类通常至少包含以下四种:
(1)COM接口类
  每个COM DLL中都包含一组接口类(它们的类名通常以大写字母I开头),每个接口类都是继承自标准COM接口(IUnkonw或IDispatch接口)的C++抽象类,接口中定义了一些public类型的纯虚函数,这些函数会被若干个COM组件类所实现。
  用户调用COM组件,大多数情况下调用的就是COM组件中的COM接口类,更确切的说是定义在COM接口类中的的函数。然而,COM开发规范要求COM接口必须实现为抽象类,因此用户无法直接实例化COM接口类进行调用。但是,COM接口类在COM DLL中是会被COM组件类所实现的,因此用户通常是采用多态的方式调用COM DLL的,其一般调用流程为:创建COM实现类对象—>将对象传递给其所实现的COM接口类—>调用COM接口类中的函数。
(2)COM实现类
  由于COM接口类是抽象的,因此要想让外部能够调用COM DLL中的COM接口,则必须在COM DLL中定义一个或多个类去实现这些COM接口,这些类就是COM实现类(也有某些场合称为COM组件类),由COM实现类创建出来的对象就称为COM对象。通常情况下,在COM DLL中COM接口类和COM实现类都是一对一的,但也有很多COM DLL会将实现类和接口类组织成多继承或钻石继承的模式。但对调用COM DLL的用户来说,其并不需要关心COM实现类,而只需要关心COM DLL提供了哪些可以调用的COM接口,以及这些COM接口相互之间的依赖关系即可。
(3)COM 工厂类
  正如之前所说,用户调用COM DLL通常是先创建COM实现类对象,然后将对象转型为COM接口类对象进行调用。然而COM实现类并不能像普通C++类那样直接采用new或声明式的方法去创建其对象,而应调用Windows SDK中提供的一组特殊的函数去创建它们的对象(这组函数的用法详见“六 COM库函数”)。
  用户在调用COM库函数创建COM实现类对象时,COM库函数实际上会先调用COM DLL的导出函数创建其所包含的COM工厂类的对象,然后通过它来创建COM实现类的对象并将其返回给用户,也就是说COM对象的创建实际上是在COM DLL的工厂类中完成的,而不是在调用COM DLL的应用程序中完成的。
  COM工厂类是一种继承自标准COM接口IClassFactory的类,COM工厂类类似于工厂设计模式中的工厂类,其主要用于创建COM DLL中所包含的COM实现类的对象。通常情况下,COM DLL中的每个COM实现类都需要定义一个与之对应的工厂类,但也可以只在COM DLL中定义一个工厂类,然后在这个工厂类中去创建所有COM实现类的对象(工厂类用法详见“四 COM工厂类”)。
(4)COM导出函数
  COM导出函数是COM DLL导出给外部调用的一组DLL导出函数,这些函数用于注册/卸载COM组件,以及返回COM工厂类的实例等。COM导出函数都具有固定的名称和参数,其主要包括:组件入口函数、组件注册函数、组件卸载函数、组件工厂类获取函数(COM导出函数用法详见“五 COM导出函数”)。
  一个简单的COM DLL所包含的类实现如下:

//COM接口类
class IMyComInterface:public IUnknow
{
public:
	virtual void func()=0;
}

//COM实现类
class MyComInterface:public IMyComInterface
{
public:
	@override;
	STDMETHODIMP QueryInterface(REFIID riid, void **ppv);		  
	@override;	
	void func()
	{
		cout<<"I'm implementation class of IMyComInterface";
	};
}

//COM工厂类
class MyComInterfaceFactory:public IClassFactory
{
public:
	@override;
	STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
	@override;
	HRESULT CreateInstance(LPUNKNOW pUnk,REFIID riid, void **ppv); 
	@override;
	HRESULT LockServer(Bool fLock);
}

//COM导出函数
DllCanUnloadNow()
DllGetClassObject()
DllRegisterServer()
DllUnregisterServer()

1.3 COM库函数

  COM库函数包含在Windows SDK提供的一个用于调用COM组件的函数库中,其包括GUID查询和转换函数、COM组件对象创建函数等等(COM库函数用法详见“六 COM库函数”)。
  如下演示了在C++环境中使用COM库函数创建并调用COM组件的基本过程。

#include <Windows.h>
int main()
{
	//初始化COM库
	CoInitialize(NULL)
	
	//创建COM对象
	IMyComInterface* pMyComInterface;
    CoCreateInstance(CLSID_MyComInterface, NULL, CLSCTX_INPROC_SERVER, IID_MyComInterface,&pMyComInterface);
	
	//调用COM对象
	pMyComInterface->func();
	
	//卸载COM库
	CoUnInitialize(NULL)
}

1.4 COM客户端

  COM客户端是调用COM组件的一端,COM客户端在调用COM组件时首先需要借助COM库函数的API创建相应的COM组件对象,然后将其转型为相应的COM接口类的对象,然后再调用COM接口类中的函数来实现想要的功能。
  COM客户端与COM组件是环境隔离的,所谓环境隔离是指COM客户端与COM组件之间不存在任何环境依赖,两者的开发语言可以不同,两者所用编译器也可以不同,两者可执行文件的形式都可以不同,例如可以在C++中调用Java编写的COM组件等等。
  

2 COM技术特点

  COM是实现面向组件编程以及构建可复用软件的一种有效的手段,这主要源于COM技术的以下几个特点:

2.1 平台语言无关性

  COM实际上并不局限于Windows平台以及C++语言,因为COM它只是制定了一套通用的组件开发规范,这些规范并没有与具体的语言和平台进行绑定,Windows下的COM只是此标准的一种实现。
  COM是一套跨平台以及跨语言的组件开发规范,不管用户使用何种语言开发组件,也不管该组件运行在何种平台,只要开发的组件符合COM规范的要求,那么其它的应用程序就能够基于COM规范来正确的调用它。

2.2 位置透明性

  在Windows系统上,COM组件通过在注册表记录自身可执行文件的位置以及CLSID来向用户公布它的存在。用户在调用COM组件时只需向COM库函数传入适当的CLSID或PROGID即可,并不需要知道其可执行文件的位置。这使得COM组件的可执行文件既可以存于本地,也可以存在于远程(这种COM组件为分布式COM组件,简称DCOM)。同时还能够随意的调动位置而不影响客户程序的使用(每次调动位置时只需要在系统中重新注册一下即可)。

2.3 版本兼容性

  COM组件中的每个接口都有一个固定的ID(IID)。用户在调用组件接口的某个函数时首先需要向IUnknow::QueryInterface()传入合适的IID来获取该组件的接口实例,这使得COM组件实现版本向后兼容变得十分简单:升级COM组件时,不改变原有已经定义的任何接口类,而是增加新的接口类来实现新的功能。这样一来,需要使用新版COM组件接口的用户直接向IUnknow::QueryInterface()传入新接口的IID即可,而原有使用旧版COM组件接口的用户仍能使用旧接口的IID正常运行。

2.4 即插即用性

  COM组件是以动态链接的方式加载运行的,客户程序可以在运行过程中动态的对其载入或卸出。

2.5 信息封装性

  COM组件是以COM接口或IDispatch接口向外提供服务的,组件的实现完全隐藏在了COM实现类中。这使得一方面COM客户端和COM服务端能够完全隔离开来,另一方面这使得客户端能够与服务端采用一套通用的接口进行通信。这种特性在保证了组件开发灵活性的前提下,又极大的方便了客户端的调用。

Activiti是一个轻量级的开源工作流引擎,支持BPMN 2.0规范,非常适合实现企业中的各种流程管理需求。Activiti 5.22.0是其开发指南的版本之一。 Activiti 5.22.0开发指南提供了详细的技术指导,帮助开发人员快速理解和上手Activiti工作流引擎。它包含了工作流引擎的架构、组件、配置和部署等基础知识,以及如何进行流程定义、任务管理、用户认证、历史数据记录等高级功能的开发开发指南通常包括以下几个重要的主题: 1. Activiti的概述:介绍Activiti的基本概念、架构和特点,帮助开发人员了解工作流引擎的基本原理。 2. 开发环境搭建:指导开发人员如何配置和搭建开发环境,包括安装所需的Java开发工具和Activiti工作流引擎。 3. 流程定义开发:详细介绍如何使用BPMN 2.0规范定义流程,包括流程图的绘制和各个节点的配置。 4. 任务管理开发:演示如何创建、分配和处理任务,以及如何使用Activiti的API进行任务查询和管理。 5. 用户认证与权限控制:介绍如何集成认证机制,例如基于数据库的用户认证,以及如何通过角色和权限控制来管理用户的访问权限。 6. 历史数据记录与报表统计:解释如何通过配置和API使用Activiti记录历史数据,以及如何使用Activiti提供的报表统计功能。 通过学习Activiti 5.22.0开发指南开发人员可以系统地掌握Activiti工作流引擎的开发技能,快速构建出符合企业需求的流程管理系统,并提供完善的用户体验和高效的业务处理能力。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值