版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、构件对象模型构件对象模型:COM 自动化自动化DCOM(1) COM的来源的来源 源于源于OLE: Object Link and Embedding OLE1 采用采用DDE(Dynamic Data Exchange) 在不同的程序之间进展通讯在不同的程序之间进展通讯DDE缺陷缺陷: 效率低效率低,稳定性不好稳定性不好,运用不方便运用不方便 COM是为抑制上述缺乏而出现的是为抑制上述缺乏而出现的 OLE2 以以 COM 为根底为根底 但但OLE未能表达未能表达COM优点优点 1 综述综述(2)什么是什么是COM 构件对象模型构件对象模型:Component Object Model 客户与
2、构件为了可以互操作而遵照的规范客户与构件为了可以互操作而遵照的规范 COM规范包括规范与实现两部分规范包括规范与实现两部分规范部分定义了构件之间的通讯机制规范部分定义了构件之间的通讯机制这些规范不依赖于任何特定的言语这些规范不依赖于任何特定的言语和操作系统和操作系统实现部分即实现部分即COM库库为为COM规范的详细实现提供一些中心效力规范的详细实现提供一些中心效力(3) COM构件构件以以 DLL或或EXE方式发布的代码方式发布的代码与言语无关与言语无关以二进制方式发布以二进制方式发布可以在不妨碍客户的方式下被晋级可以在不妨碍客户的方式下被晋级可以透明地在网络上被重新分配可以透明地在网络上被重
3、新分配构件与类构件与类:一个构件可以由多个类实现一个构件可以由多个类实现接口与类接口与类:一个类可以实现多个接口一个类可以实现多个接口(4) COM库库 (COM Library)功能功能: (1)实现客户方与效力器方实现客户方与效力器方COM运用的创建过程运用的创建过程(2)COM经过注册表查找本地效力器经过注册表查找本地效力器(即即EXE程序程序) 以及程序名与以及程序名与CLSID的转换的转换(3)提供规范的内存控制方法提供规范的内存控制方法DCOM的实现提供了分布式环境下的通讯机制的实现提供了分布式环境下的通讯机制在操作系统层次在操作系统层次 以以DLL文件的方式存在文件的方式存在(5
4、) COM特性特性言语无关性言语无关性为跨言语协作开发提供了一致规范为跨言语协作开发提供了一致规范并得到不同集成开发环境的支持并得到不同集成开发环境的支持 进程透明性进程透明性进程内效力程序进程内效力程序: DLL本地效力程序本地效力程序: EXE远地效力程序远地效力程序: DLL或或EXE实现进程透明性的关键是实现进程透明性的关键是COM库库它担任效力体的定位它担任效力体的定位 管理对象的创建及对象与客户之间的通讯管理对象的创建及对象与客户之间的通讯复用性复用性包含方式包含方式 聚合方式聚合方式(6) COM开展趋势开展趋势操作系统操作系统 成为系统的根本软件模型成为系统的根本软件模型数据库
5、数据库 OLE DB/ADO 以以 COM 的方式的方式为数据访问提供一致的接口为数据访问提供一致的接口Internet ActiveX包含了一切基于包含了一切基于COM的的Internet相关技术相关技术COM+添加添加MTS等效力等效力2 COM接口接口COM接口是接口是COM规范的中心内容规范的中心内容接口的意义接口的意义(略略)一个接口包含了一组函数一个接口包含了一组函数在在C+中中, 可以用笼统基类来定义可以用笼统基类来定义COM接口接口接口的实现接口的实现 : vtbl 指针指针 虚拟函数表虚拟函数表Vtbl指针指针虚拟函数表虚拟函数表pIX接口的内存构造接口的内存构造IX&
6、;Fx1&Fx2&Fx3&Fx4Vtbl的作用的作用:提高接口实现的灵敏性提高接口实现的灵敏性例子例子:一个实现接口一个实现接口IX的类的类CA,CA包含包含2个数据个数据:Vtbl指针指针虚拟函数表虚拟函数表IX&Fx1&Fx2&Fx3&Fx4Data1Data2pAFx1Fx2Fx3Fx4CA两个实例两个实例 共享同一共享同一Vtbl:Vtbl指针指针虚拟函数表虚拟函数表&Fx1&Fx2&Fx3&Fx4Data1Data2pA1pA2Fx1Fx2Fx3Fx4CAVtbl指针指针Data1Data2 接口
7、特点接口特点实现级实现级二进制,独立于编程言语二进制,独立于编程言语稳定性稳定性客户与效力器依赖于接口客户与效力器依赖于接口承继性承继性便于扩展接口便于扩展接口, 不提倡承继不提倡承继一切接口皆承继一切接口皆承继Iunknown多态性:多态性:1功能功能提供:提供:生存期控制生存期控制接口查询接口查询 IUnknown的定义的定义IDL:interface IUnkownvirtual HRESULT QueryInterface(const IID&, void *ppv) = 0;virtual ULONG AddRef() = 0;virtual ULONG Release()
8、= 0;Vtbl指针指针虚拟函数表虚拟函数表IXQueryInterfaceAddRefRelease&FxpAQueryInterfaceAddRefReleaseFxCA一切接口都必需承继一切接口都必需承继IUnknownIUnknown指针的获取指针的获取 IUnknown * CreateInstance();创建构件时,客户可以运用创建构件时,客户可以运用CreateInstance, 而不是而不是new。CreateInstance的定义:的定义: IUnknown * CreateInstance() IUnknown * pI = static_cast (new fo
9、o); pI - AddRef(); return pI; 援用计数的实现方式援用计数的实现方式:在什么层次上进展计数在什么层次上进展计数构件构件对象对象接口接口构件构件构件援用记数构件援用记数对象援用记数对象援用记数对象援用记数对象援用记数对象对象1对象对象2接口接口接口接口接口接口接口接口接口援用记数接口援用记数接口援用记数接口援用记数接口援用记数接口援用记数接口援用记数接口援用记数一个一个COM对象构件可以实现多个接口对象构件可以实现多个接口运用运用QueryInterface查询某个构件能否支持某个特定的接口查询某个构件能否支持某个特定的接口 QueryInterface的运用的运用
10、void foo(Iunknown * pI)/Define a pointer for the interface.IX * pIX = NULL;/Ask for nterface IXHRESULT hr = pI-QueryUbterface(IID_IX, (void *)&pIX);/Check return value.If (SUCCEEDED(hr) / Use interfacepIX-Fx();* ppv)static_cast(*ppv)-AddRef();return S_OK;QueryInterface前往的总是同一个前往的总是同一个IUnknown指针指
11、针假设客户曾经获取过某个接口假设客户曾经获取过某个接口,那么它将总能获取此接口那么它将总能获取此接口客户可以再次获取曾经拥有的接口客户可以再次获取曾经拥有的接口客户可以前往到起始接口客户可以前往到起始接口假设可以从某个接口获取某特定接口假设可以从某个接口获取某特定接口那么可以从那么可以从(该构件的该构件的)恣意接口获取此接口恣意接口获取此接口COM接口永远不会变化接口永远不会变化 :一个一个IID就是一个接口就是一个接口 经过发行新版本构件处理兼容性经过发行新版本构件处理兼容性当以下条件中的任何一个变化时当以下条件中的任何一个变化时应给新接口指定新应给新接口指定新IID:接口中函数数目接口中函
12、数数目接口中函数顺序接口中函数顺序某个函数的参数某个函数的参数某个函数参数的顺序某个函数参数的顺序某个函数参数的类型某个函数参数的类型函数能够的前往值函数能够的前往值函数前往值的类型函数前往值的类型等等不同版本接口的命名不同版本接口的命名:在老称号后加一个数字在老称号后加一个数字(1)预备知识预备知识:DLLDLL是一个构件效力器是一个构件效力器EXE也可以是构件效力器也可以是构件效力器运用户在运用程序的运转过程中交换构件运用户在运用程序的运转过程中交换构件构件是构件是DLL中实现的接口集中实现的接口集DLL共享它们所链入的运用程序地址空间共享它们所链入的运用程序地址空间HRESULT向用户报
13、告构件运转结果情况向用户报告构件运转结果情况“Here is the RESULTWINERROR.H中进展定义中进展定义用户可以定义本人的代码用户可以定义本人的代码GUID: Globally Unique IDentifier用于标识构件用于标识构件(CLSID)与接口与接口(IID)128位位(长整数长整数)由于空间足够大由于空间足够大 接口标识冲突较小接口标识冲突较小可以用编程的方法生成具有独一性的可以用编程的方法生成具有独一性的GUIDVC: UUIDGEN.EXE, GUIDGEN.EXE自创了自创了OSF的的UUID(DCE中的中的RPC运用运用).对对GUID值的传送通常经过援
14、用进展值的传送通常经过援用进展CLSID:CLaSs IDentifierWindows 注册表注册表Windows操作系统的共享系统数据库操作系统的共享系统数据库包括包括 硬件硬件 软件软件 配置及用户等各种信息配置及用户等各种信息由由REGEDIT.EXE (95/98) REGEDIT32.EXE(NT) 启动启动可以运用可以运用REGSVR32.EXE来注册某个构件来注册某个构件注册表是一个由许多元素构成的层次构造注册表是一个由许多元素构成的层次构造每一个元素均被称作是一个关键字每一个元素均被称作是一个关键字每一个关键字可以包含一系列子关键字等每一个关键字可以包含一系列子关键字等 例如
15、:例如:HKEY_CLASSES_ROOTCLSIDProgID 等等2COM库库COM构件与客户皆需求完成的一样操作构件与客户皆需求完成的一样操作由由OLE32.DLL、OLE32.LIB实现实现COM库中常用的函数:库中常用的函数:初始化函数初始化函数与与GUID相关的函数相关的函数对象创建函数对象创建函数内存管理函数内存管理函数 在运用在运用COM库中的其他函数除库中的其他函数除CoBuildVersion之前,进程必需先调用:之前,进程必需先调用:HRESULT CoInitialize(void * reserved) 在退出之前调用:在退出之前调用:void CoUninitial
16、ize(void * reserved) 其他:其他:CoBuildVersionCoFreeUnusedLibraries OleInitialize建立在建立在CoInitialize根底之上根底之上 DCOM运用运用CoInitializeEx初始化函数:初始化函数:与与GUID(CLSID)相关的函数:相关的函数:例如:将例如:将GUID转换为一个字符串:转换为一个字符串:wchar_t szCLSID39;int r = : StringFromGUID2(CLSID_Component1, szCLSID, 39);其它:其它:StringFromCLSIDStringFromII
17、DCLSIDFromStringIIDFromStringIsEqualGUIDIsEqualIIDIsEqualCLSIDCLSIDFromProgID对象创建函数:对象创建函数:CoGetClassObjectCoCreateInstanceCoCreateInstanceExCoRegisterClassObjectCoRevokeClassObjectCoDisconnectObject内存管理函数:内存管理函数:CoTaskMemAllocCoTaskMemReallocCoTaskMemFreeCoGerMalloc可以创建其他构件的构件可以创建其他构件的构件(构件厂构件厂)其本身
18、也是一个其本身也是一个COM对象对象支持一个特殊的接口支持一个特殊的接口 IClassFacroty每一个每一个COM对象类应该有一个相应的类厂对象对象类应该有一个相应的类厂对象CoCreateInstanceCOM库函数之一库函数之一HRESULT_stdcall CoCreateInstance(const CLSID& clsid,Iunkown * pIUnknownOuter,DWORD dwClsContext,const IID& iid,void * ppv);clsid:待创建构件的标识;待创建构件的标识;pIUnknownOuter:用于聚合;:用于聚合;d
19、wClsContext:限定所创建构件的上下文;:限定所创建构件的上下文;iid:构件上待运用接口的标识;:构件上待运用接口的标识;ppv:所前往接口的指针。:所前往接口的指针。一个运用例子:一个运用例子:IX * pIX = NULL;HRESULT he = :CoCreateInstance( CLSID_Component1,NULL,CLSCTX_INPROC_SERVER,IID_IDX,(void *) &pIX);if (SUCCEEDED(hr) pIX - FX();pIX - Release();类厂类厂CoCreateInstance实践上实践上未直接创建未直接
20、创建COM构件构件创建了一个被称为类厂的构件创建了一个被称为类厂的构件类厂构件的独一功能是创建其他构件类厂构件的独一功能是创建其他构件客户可以经过类厂所支持的接口来客户可以经过类厂所支持的接口来对类厂创建对类厂创建构件的过程加以控制构件的过程加以控制CoCreateInstance调用调用CoGetClassObject创建构件的规范接口是创建构件的规范接口是IClassFactoryCoGetClassObject创建类厂创建类厂HRESULT_stdcall CoGetClassObject(const CLSID& clsid,DWORD dwClsContext,COSERVE
21、RINFO * pServerInfo,/用于用于DCOMconst IID& iid,void * ppv /指向类厂中某个接口的指针指向类厂中某个接口的指针);IClassFactory 用于创建构件的规范接口用于创建构件的规范接口Interface IClassFactory: IUnknownHRESULT _stdcallCreateInstance( IUnknown * pUnknownOuter,const IID & iid,void * ppv );HRESULT _stdcall LockServer(BOOL block);未接纳未接纳CLSID:只能创
22、建同某个:只能创建同某个CLSID相应的构件相应的构件IClassFactory2CoCreateInstance 与与 CoGetClassObject的关系:的关系:CoCreateInstance 经过经过 CoGetClassObject实现实现HRESULT CoCreateInstance(const CLSID& clsid,IUnknown * pUnknownDuter,DWOED dwClsContext,const IID& iid,void * ppv)* ppv = NULL;IClassFactory * pIFactory = NULL;HRESU
23、LT hr = CoGetClassObject(clsid, dwClsContext, NULL, IID_IClassFactory, (void)* &pIFactory);if (SUCCEEDED(hr)hr=pIFactory-CreateInstance(pUnknownOuter, iid, ppv);pIFactory - Release();return hr;在以下情况下应直接运用在以下情况下应直接运用CoGetClassObject 而应运用而应运用CoCreateInstance:(1)假设希望用不同于假设希望用不同于IClassFactory的某个创建接口
24、的某个创建接口来创建构件来创建构件 例如例如 IClassFactory2(2)假设希望创建同一构件的多个实例假设希望创建同一构件的多个实例4类厂的实现类厂的实现CoGetClassObject需求需求DLL中的一个特定的函数中的一个特定的函数来创建构件的类厂来创建构件的类厂DllGetClassObject:STDAPI DllGetClassObject(const CLSID& clsid,const IID& iid,void * ppv);创建、调用构件的过程:创建、调用构件的过程:客户客户COM库库DLLCoGetClassObject调用调用CoGetClassO
25、bjectDllGetClassObjectIClassFactoryIXpIClassFactorypIX创建类厂创建类厂创建构件创建构件前往前往IClassFactory调用调用IClassFactory:CreateInstance前往前往IX调用调用IX:Fx#include #include #include Iface.hint main()CoInitialize(NULL) ;IX* pIX = NULL ; HRESULT hr = :CoCreateInstance(CLSID_Component1,NULL, CLSCTX_INPROC_SERVER, IID_IX, (
26、void*)&pIX) ;if (SUCCEEDED(hr)pIX-Fx() ; / Use interface IX.IY* pIY = NULL ;hr = pIX-QueryInterface(IID_IY, (void*)&pIY) ;if (SUCCEEDED(hr)pIY-Fy() ; / Use interface IY.pIY-Release() ;客户方代码客户方代码5例子例子IZ* pIZ = NULL ;hr = pIX-QueryInterface(IID_IZ, (void*)&pIZ) ;if (SUCCEEDED(hr)pIZ-Fz() ;
27、pIZ-Release() ;pIX-Release() ;elsecout Client: ttCould not create component. hr = hex hr endl ; / Uninitialize COM LibraryCoUninitialize() ;return 0 ;#include #include #include Iface.h / Interface declarations#include Registry.h / Registry helper functionsstatic HMODULE g_hModule = NULL ; / DLL modu
28、le handlestatic long g_cComponents = 0 ; / Count of active componentsstatic long g_cServerLocks = 0 ; / Count of locks/ Friendly name of componentconst char g_szFriendlyName = Inside COM, Ch 7 Example ;/ Version-independent ProgIDconst char g_szVerIndProgID = InsideCOM.Chap07 ;效力器方代码效力器方代码class CA :
29、 public IX, public IY public:/ IUnknownvirtual HRESULT _stdcall QueryInterface(const IID& iid, void* ppv) ;virtual ULONG _stdcall AddRef() ;virtual ULONG _stdcall Release() ;/ Interface IXvirtual void _stdcall Fx() cout Fx endl ;/ Interface IYvirtual void _stdcall Fy() cout Fy endl ; / Construct
30、orCA() ;/ DestructorCA() ;private:/ Reference countlong m_cRef ; ;HRESULT _stdcall CA:QueryInterface(const IID& iid, void* ppv)if (iid = IID_IUnknown)*ppv = static_cast(this) ; else if (iid = IID_IX)*ppv = static_cast(this) ;else if (iid = IID_IY)*ppv = static_cast(this) ; else*ppv = NULL ;retur
31、n E_NOINTERFACE ;reinterpret_cast(*ppv)-AddRef() ;return S_OK ;class CFactory : public IClassFactorypublic:/ IUnknownvirtual HRESULT _stdcall QueryInterface(const IID& iid, void* ppv) ; virtual ULONG _stdcall AddRef() ;virtual ULONG _stdcall Release() ;/ Interface IClassFactoryvirtual HRESULT _s
32、tdcall CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void* ppv) ;virtual HRESULT _stdcall LockServer(BOOL bLock) ; / ConstructorCFactory() : m_cRef(1) / DestructorCFactory() private:long m_cRef ; ;HRESULT _stdcall CFactory:QueryInterface(const IID& iid, void* ppv)if (iid = IID_IUnk
33、nown) | (iid = IID_IClassFactory)*ppv = static_cast(this) ; else *ppv = NULL ;return E_NOINTERFACE ;reinterpret_cast(*ppv)-AddRef() ;return S_OK ;ULONG _stdcall CFactory:AddRef()return InterlockedIncrement(&m_cRef) ;ULONG _stdcall CFactory:Release() if (InterlockedDecrement(&m_cRef) = 0)dele
34、te this ;return 0 ;return m_cRef ;/ IClassFactory implementationHRESULT _stdcall CFactory:CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void* ppv) if (pUnknownOuter != NULL)return CLASS_E_NOAGGREGATION ;CA* pA = new CA ;if (pA = NULL)return E_OUTOFMEMORY ;HRESULT hr = pA-QueryInterface(iid, ppv) ;/ Release the IUnknown pointer./ (If QueryInterface failed, com
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年超市数字化运营面试题库及答案
- 2025年平顶山医美中心面试题库及答案
- 2025年江苏省事业单位面试题库及答案
- 2025年惠州业务员笔试题目及答案
- 2025年三选一二选一面试题库及答案
- 2025年六盘水教师面试题库答案
- 餐饮业经营模式研究与探讨
- 超算技术实现方法介绍
- 华工科技深度研究:全球光模块机遇已至光电领军企业乘势而起
- 某家政公司扫地机使用规范
- ISO 55001-2025 资产管理-资产管理体系-要求(中文版-翻译-2025)
- django基于深度学习的旅游系统设计与实现-论文13000字
- 《采煤机》课件-第二章 采煤机截割部
- 医院复工复产安全培训课件
- 民营企业工作作风存在的问题及整改措施
- GB/T 6075.6-2024机械振动在非旋转部件上测量评价机器的振动第6部分:功率大于100 kW的往复式机器
- 2025年湖南劳动人事职业学院高职单招职业技能测试近5年常考版参考题库含答案解析
- 教学大纲-跨境电子商务法律法规
- 肺曲霉病护理
- 上海市历年中考语文现代文之议论文阅读6篇(含答案)(2003-2022)
- 重症感染治疗指南
评论
0/150
提交评论