书签 分享 收藏 举报 版权申诉 / 54
上传文档赚钱

类型高级软件工程06(COM基础:接口与实现).ppt

  • 上传人(卖家):罗嗣辉
  • 文档编号:2046209
  • 上传时间:2022-01-21
  • 格式:PPT
  • 页数:54
  • 大小:153KB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《高级软件工程06(COM基础:接口与实现).ppt》由用户(罗嗣辉)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    高级 软件工程 06 COM 基础 接口 实现
    资源描述:

    1、1构件对象模型构件对象模型:COM2基础部分基础部分综述综述接口接口实现实现高级部分高级部分包含与聚合包含与聚合COM与与VC自动化自动化DCOM3(1) COM的起源的起源 源于源于OLE: Object Link and Embedding OLE1 采用采用DDE(Dynamic Data Exchange) 在不同的程序之间进行通信在不同的程序之间进行通信DDE缺点缺点: 效率低效率低,稳定性不好稳定性不好,使用不方便使用不方便 COM是为克服上述不足而出现的是为克服上述不足而出现的 OLE2 以以 COM 为基础为基础 但但OLE未能体现未能体现COM优点优点 1 综述综述4(2)什

    2、么是什么是COM 构件对象模型构件对象模型:Component Object Model 客户与构件为了能够互操作而遵循的标准客户与构件为了能够互操作而遵循的标准 COM标准包括规范与实现两部分标准包括规范与实现两部分规范部分定义了构件之间的通信机制规范部分定义了构件之间的通信机制这些规范不依赖于任何特定的语言这些规范不依赖于任何特定的语言和操作系统和操作系统实现部分即实现部分即COM库库为为COM规范的具体实现提供一些核心服务规范的具体实现提供一些核心服务5(3) COM构件构件以以 DLL或或EXE形式发布的代码形式发布的代码与语言无关与语言无关以二进制形式发布以二进制形式发布可以在不妨碍

    3、客户的形式下被升级可以在不妨碍客户的形式下被升级可以透明地在网络上被重新分配可以透明地在网络上被重新分配构件与类构件与类:一个构件可以由多个类实现一个构件可以由多个类实现接口与类接口与类:一个类可以实现多个接口一个类可以实现多个接口6(4) COM库库 (COM Library)功能功能: (1)实现客户方与服务器方实现客户方与服务器方COM应用的创建过程应用的创建过程(2)COM通过注册表查找本地服务器通过注册表查找本地服务器(即即EXE程序程序) 以及程序名与以及程序名与CLSID的转换的转换(3)提供标准的内存控制方法提供标准的内存控制方法DCOM的实现提供了分布式环境下的通信机制的实现

    4、提供了分布式环境下的通信机制在操作系统层次在操作系统层次 以以DLL文件的形式存在文件的形式存在7(5) COM特性特性语言无关性语言无关性为跨语言合作开发提供了统一标准为跨语言合作开发提供了统一标准并得到不同集成开发环境的支持并得到不同集成开发环境的支持 进程透明性进程透明性进程内服务程序进程内服务程序: DLL本地服务程序本地服务程序: EXE远地服务程序远地服务程序: DLL或或EXE实现进程透明性的关键是实现进程透明性的关键是COM库库它负责服务体的定位它负责服务体的定位 管理对象的创建及对象与客户之间的通信管理对象的创建及对象与客户之间的通信复用性复用性包含方式包含方式 聚合方式聚合

    5、方式8(6) COM发展趋势发展趋势操作系统操作系统 成为系统的基本软件模型成为系统的基本软件模型数据库数据库 OLE DB/ADO 以以 COM 的方式的方式为数据访问提供一致的接口为数据访问提供一致的接口Internet ActiveX包含了所有基于包含了所有基于COM的的Internet相关技术相关技术COM+增加增加MTS等服务等服务92 COM接口接口COM接口是接口是COM规范的核心内容规范的核心内容接口的意义接口的意义(略略)一个接口包含了一组函数一个接口包含了一组函数在在C+中中, 可以用抽象基类来定义可以用抽象基类来定义COM接口接口接口的实现接口的实现 : vtbl 指针指

    6、针 虚拟函数表虚拟函数表10Vtbl指针指针虚拟函数表虚拟函数表pIX接口的内存结构接口的内存结构IX&Fx1&Fx2&Fx3&Fx411Vtbl的作用的作用:提高接口实现的灵活性提高接口实现的灵活性例子例子:一个实现接口一个实现接口IX的类的类CA,CA包含包含2个数据个数据:Vtbl指针指针虚拟函数表虚拟函数表IX&Fx1&Fx2&Fx3&Fx4Data1Data2pAFx1Fx2Fx3Fx4CA12两个实例两个实例 共享同一共享同一Vtbl:Vtbl指针指针虚拟函数表虚拟函数表&Fx1&Fx2&Fx3&Fx4Data1Data2pA1pA2Fx1Fx2Fx3Fx4CAVtbl指针指针Da

    7、ta1Data213 接口特点接口特点实现级实现级二进制,独立于编程语言二进制,独立于编程语言稳定性稳定性客户与服务器依赖于接口客户与服务器依赖于接口继承性继承性便于扩展接口便于扩展接口, 不提倡继承不提倡继承所有接口皆继承所有接口皆继承Iunknown)多态性:多态性:14(1)功能)功能提供:提供:生存期控制生存期控制接口查询接口查询 IUnknown的定义(的定义(IDL):):interface IUnkownvirtual HRESULT QueryInterface(const IID&, void *ppv) = 0;virtual ULONG AddRef() = 0;virt

    8、ual ULONG Release() = 0;15Vtbl指针指针虚拟函数表虚拟函数表IXQueryInterfaceAddRefRelease&FxpAQueryInterfaceAddRefReleaseFxCA所有接口都必须继承所有接口都必须继承IUnknown16IUnknown指针的获取指针的获取 IUnknown * CreateInstance();创建构件时,客户可以使用创建构件时,客户可以使用CreateInstance, 而不是而不是new。CreateInstance的定义:的定义: IUnknown * CreateInstance() IUnknown * pI =

    9、 static_cast (new foo); pI - AddRef(); return pI; 17AddRef与与Release控制构件的生命期控制构件的生命期解决内存管理问题解决内存管理问题使构件能够自己将自己删除使构件能够自己将自己删除使用规则使用规则返回接口指针之前调用返回接口指针之前调用 AddRef;使用完接口之后调用使用完接口之后调用Release;赋值之后调用赋值之后调用AddRef;18引用计数的实现方式引用计数的实现方式:在什么层次上进行计数在什么层次上进行计数构件构件对象对象接口接口构件构件构件引用记数构件引用记数对象引用记数对象引用记数对象引用记数对象引用记数对象对

    10、象1对象对象2接口接口接口接口接口接口接口接口接口引用记数接口引用记数接口引用记数接口引用记数接口引用记数接口引用记数接口引用记数接口引用记数19一个一个COM对象(构件)可以实现多个接口对象(构件)可以实现多个接口使用使用QueryInterface查询某个构件是否支持某个特定的接口查询某个构件是否支持某个特定的接口 void foo(Iunknown * pI)/Define a pointer for the interface.IX * pIX = NULL;/Ask for nterface IXHRESULT hr = pI-QueryUbterface(IID_IX, (void

    11、 *)&pIX);/Check return value.If (SUCCEEDED(hr) / Use interfacepIX-Fx();20 假定存在类假定存在类 CA,继承接口继承接口 IX 与与 IY: HRESULT _sfdcall 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 =

    12、static_cast(this);else *ppv = NULL; return E_NOINTERFACE;static_cast(*ppv)-AddRef();return S_OK;21QueryInterface返回的总是同一个返回的总是同一个IUnknown指针指针若客户曾经获取过某个接口若客户曾经获取过某个接口,那么它将总能获取此接口那么它将总能获取此接口客户可以再次获取已经拥有的接口客户可以再次获取已经拥有的接口客户可以返回到起始接口客户可以返回到起始接口若能够从某个接口获取某特定接口若能够从某个接口获取某特定接口则可以从则可以从(该构件的该构件的)任意接口获取此接口任意接口

    13、获取此接口22COM接口永远不会变化接口永远不会变化 :一个一个IID就是一个接口就是一个接口 通过发行新版本构件解决兼容性通过发行新版本构件解决兼容性当下列条件中的任何一个变化时当下列条件中的任何一个变化时应给新接口指定新应给新接口指定新IID:接口中函数数目接口中函数数目接口中函数顺序接口中函数顺序某个函数的参数某个函数的参数某个函数参数的顺序某个函数参数的顺序某个函数参数的类型某个函数参数的类型函数可能的返回值函数可能的返回值函数返回值的类型函数返回值的类型等等不同版本接口的命名不同版本接口的命名:在老名称后加一个数字在老名称后加一个数字23(1)预备知识预备知识:DLLDLL是一个构件

    14、服务器是一个构件服务器EXE也可以是构件服务器也可以是构件服务器使用户在应用程序的运行过程中替换构件使用户在应用程序的运行过程中替换构件构件是构件是DLL中实现的接口集中实现的接口集DLL共享它们所链入的应用程序地址空间共享它们所链入的应用程序地址空间HRESULT向用户报告构件运行结果状况向用户报告构件运行结果状况“Here is the RESULT”WINERROR.H中进行定义中进行定义用户可以定义自己的代码用户可以定义自己的代码24GUID: Globally Unique IDentifier用于标识构件用于标识构件(CLSID)与接口与接口(IID)128位位(长整数长整数)由于

    15、空间足够大由于空间足够大 接口标识冲突较小接口标识冲突较小可以用编程的方法生成具有唯一性的可以用编程的方法生成具有唯一性的GUIDVC: UUIDGEN.EXE, GUIDGEN.EXE借鉴了借鉴了OSF的的UUID(DCE中的中的RPC使用使用).对对GUID值的传递通常通过引用进行值的传递通常通过引用进行CLSID:CLaSs IDentifier25Windows 注册表注册表Windows操作系统的共享系统数据库操作系统的共享系统数据库包括包括 硬件硬件 软件软件 配置及用户等各种信息配置及用户等各种信息由由REGEDIT.EXE (95/98) REGEDIT32.EXE(NT) 启

    16、动启动可以使用可以使用REGSVR32.EXE来注册某个构件来注册某个构件注册表是一个由许多元素构成的层次结构注册表是一个由许多元素构成的层次结构每一个元素均被称作是一个关键字每一个元素均被称作是一个关键字每一个关键字可以包含一系列子关键字等每一个关键字可以包含一系列子关键字等 例如:例如:HKEY_CLASSES_ROOTCLSIDProgID 等等262728(2)COM库库COM构件与客户皆需要完成的相同操作构件与客户皆需要完成的相同操作由由OLE32.DLL、OLE32.LIB实现实现COM库中常用的函数:库中常用的函数:初始化函数初始化函数与与GUID相关的函数相关的函数对象创建函数

    17、对象创建函数内存管理函数内存管理函数29 在使用在使用COM库中的其他函数(除库中的其他函数(除CoBuildVersion)之前,进程必须先调用:之前,进程必须先调用:HRESULT CoInitialize(void * reserved) 在退出之前调用:在退出之前调用:void CoUninitialize(void * reserved) 其他:其他:CoBuildVersionCoFreeUnusedLibraries OleInitialize建立在建立在CoInitialize基础之上基础之上 DCOM使用使用CoInitializeEx初始化函数:初始化函数:30与与GUID

    18、(CLSID)相关的函数:相关的函数:例如:将例如:将GUID转换为一个字符串:转换为一个字符串:wchar_t szCLSID39;int r = : StringFromGUID2(CLSID_Component1, szCLSID, 39);其它:其它:StringFromCLSIDStringFromIIDCLSIDFromStringIIDFromStringIsEqualGUIDIsEqualIIDIsEqualCLSIDCLSIDFromProgID31对象创建函数:对象创建函数:CoGetClassObjectCoCreateInstanceCoCreateInstanceEx

    19、CoRegisterClassObjectCoRevokeClassObjectCoDisconnectObject内存管理函数:内存管理函数:CoTaskMemAllocCoTaskMemReallocCoTaskMemFreeCoGerMalloc32能够创建其他构件的构件能够创建其他构件的构件(构件厂构件厂)其本身也是一个其本身也是一个COM对象对象支持一个特殊的接口支持一个特殊的接口 IClassFacroty每一个每一个COM对象类应该有一个相应的类厂对象对象类应该有一个相应的类厂对象33CoCreateInstanceCOM库函数之一库函数之一HRESULT_stdcall CoC

    20、reateInstance(const CLSID& clsid,Iunkown * pIUnknownOuter,DWORD dwClsContext,const IID& iid,void * ppv);clsid:待创建构件的标识;待创建构件的标识;pIUnknownOuter:用于聚合;:用于聚合;dwClsContext:限定所创建构件的上下文;:限定所创建构件的上下文;iid:构件上待使用接口的标识:构件上待使用接口的标识;ppv:所返回接口的指针。:所返回接口的指针。34一个使用例子:一个使用例子:IX * pIX = NULL;HRESULT he = :CoCreateIns

    21、tance( CLSID_Component1,NULL,CLSCTX_INPROC_SERVER,IID_IDX,(void *) &pIX);if (SUCCEEDED(hr) pIX - FX();pIX - Release();35类厂类厂CoCreateInstance实际上实际上未直接创建未直接创建COM构件构件创建了一个被称为类厂的构件创建了一个被称为类厂的构件类厂构件的唯一功能是创建其他构件类厂构件的唯一功能是创建其他构件客户可以通过类厂所支持的接口来客户可以通过类厂所支持的接口来对类厂创建对类厂创建构件的过程加以控制构件的过程加以控制CoCreateInstance调用调用C

    22、oGetClassObject创建构件的标准接口是创建构件的标准接口是IClassFactory36CoGetClassObject创建类厂创建类厂HRESULT_stdcall CoGetClassObject(const CLSID& clsid,DWORD dwClsContext,COSERVERINFO * pServerInfo,/用于用于DCOMconst IID& iid,void * ppv /指向类厂中某个接口的指针指向类厂中某个接口的指针);37IClassFactory 用于创建构件的标准接口用于创建构件的标准接口Interface IClassFactory: IUn

    23、knownHRESULT _stdcallCreateInstance( IUnknown * pUnknownOuter,const IID & iid,void * ppv );HRESULT _stdcall LockServer(BOOL block);未接收未接收CLSID:只能创建同某个:只能创建同某个CLSID相应的构件相应的构件IClassFactory238CoCreateInstance 与与 CoGetClassObject的关系:的关系:CoCreateInstance 通过通过 CoGetClassObject实现实现HRESULT CoCreateInstance(

    24、const CLSID& clsid,IUnknown * pUnknownDuter,DWOED dwClsContext,const IID& iid,void * ppv) * ppv = NULL;IClassFactory * pIFactory = NULL;HRESULT hr = CoGetClassObject(clsid, dwClsContext, NULL, IID_IClassFactory, (void)* &pIFactory);if (SUCCEEDED(hr)hr=pIFactory-CreateInstance(pUnknownOuter, iid, ppv

    25、);pIFactory - Release();return hr;39在下列情况下应直接使用在下列情况下应直接使用CoGetClassObject 而应使用而应使用CoCreateInstance:(1)如果希望用不同于如果希望用不同于IClassFactory的某个创建接口的某个创建接口来创建构件来创建构件 例如例如 IClassFactory2(2)如果希望创建同一构件的多个实例如果希望创建同一构件的多个实例40(4)类厂的实现)类厂的实现CoGetClassObject需要需要DLL中的一个特定的函数中的一个特定的函数来创建构件的类厂来创建构件的类厂DllGetClassObject:

    26、STDAPI DllGetClassObject(const CLSID& clsid,const IID& iid,void * ppv);41创建、调用构件的过程:创建、调用构件的过程:客户客户COM库库DLLCoGetClassObject调用调用CoGetClassObjectDllGetClassObjectIClassFactoryIXpIClassFactorypIX创建类厂创建类厂创建构件创建构件返回返回IClassFactory调用调用IClassFactory:CreateInstance返回返回IX调用调用IX:Fx42#include #include #include

    27、 Iface.hint main()CoInitialize(NULL) ;IX* pIX = NULL ; HRESULT hr = :CoCreateInstance(CLSID_Component1,NULL, CLSCTX_INPROC_SERVER, IID_IX, (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 inte

    28、rface IY.pIY-Release() ;客户方代码客户方代码(5)例子)例子43IZ* pIZ = NULL ;hr = pIX-QueryInterface(IID_IZ, (void*)&pIZ) ;if (SUCCEEDED(hr)pIZ-Fz() ;pIZ-Release() ;pIX-Release() ;elsecout Client: ttCould not create component. hr = hex hr endl ; / Uninitialize COM LibraryCoUninitialize() ;return 0 ;44#include #inclu

    29、de #include Iface.h / Interface declarations#include Registry.h / Registry helper functionsstatic HMODULE g_hModule = NULL ; / DLL module handlestatic long g_cComponents = 0 ; / Count of active componentsstatic long g_cServerLocks = 0 ; / Count of locks/ Friendly name of componentconst char g_szFrie

    30、ndlyName = Inside COM, Ch 7 Example ;/ Version-independent ProgIDconst char g_szVerIndProgID = InsideCOM.Chap07 ;服务器方代码服务器方代码45class CA : public IX, public IY public:/ IUnknownvirtual HRESULT _stdcall QueryInterface(const IID& iid, void* ppv) ;virtual ULONG _stdcall AddRef() ;virtual ULONG _stdcall

    31、Release() ;/ Interface IXvirtual void _stdcall Fx() cout Fx endl ;/ Interface IYvirtual void _stdcall Fy() cout Fy endl ; / ConstructorCA() ;/ DestructorCA() ;private:/ Reference countlong m_cRef ; ;46HRESULT _stdcall CA:QueryInterface(const IID& iid, void* ppv)if (iid = IID_IUnknown)*ppv = static_c

    32、ast(this) ; else if (iid = IID_IX)*ppv = static_cast(this) ;else if (iid = IID_IY)*ppv = static_cast(this) ; else*ppv = NULL ;return E_NOINTERFACE ;reinterpret_cast(*ppv)-AddRef() ;return S_OK ;47class CFactory : public IClassFactorypublic:/ IUnknownvirtual HRESULT _stdcall QueryInterface(const IID&

    33、 iid, void* ppv) ; virtual ULONG _stdcall AddRef() ;virtual ULONG _stdcall Release() ;/ Interface IClassFactoryvirtual HRESULT _stdcall CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void* ppv) ;virtual HRESULT _stdcall LockServer(BOOL bLock) ; / ConstructorCFactory() : m_cRef(1) / Destruct

    34、orCFactory() private:long m_cRef ; ;48HRESULT _stdcall CFactory:QueryInterface(const IID& iid, void* ppv)if (iid = IID_IUnknown) | (iid = IID_IClassFactory)*ppv = static_cast(this) ; else *ppv = NULL ;return E_NOINTERFACE ;reinterpret_cast(*ppv)-AddRef() ;return S_OK ;ULONG _stdcall CFactory:AddRef(

    35、)return InterlockedIncrement(&m_cRef) ;ULONG _stdcall CFactory:Release() if (InterlockedDecrement(&m_cRef) = 0)delete this ;return 0 ;return m_cRef ;49/ IClassFactory implementationHRESULT _stdcall CFactory:CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void* ppv) if (pUnknownOuter != NULL)

    36、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, component will delete itself.)pA-Release() ;return hr ;50/ LockServerHRESULT _stdcall CFactory:LockServer(BOOL bLoc

    37、k) if (bLock)InterlockedIncrement(&g_cServerLocks) ; elseInterlockedDecrement(&g_cServerLocks) ;return S_OK ;STDAPI DllCanUnloadNow()if (g_cComponents = 0) & (g_cServerLocks = 0)return S_OK ;elsereturn S_FALSE ;51STDAPI DllGetClassObject(const CLSID& clsid, const IID& iid, void* ppv)if (clsid != CLS

    38、ID_Component1)return CLASS_E_CLASSNOTAVAILABLE ;CFactory* pFactory = new CFactory ; if (pFactory = NULL)return E_OUTOFMEMORY ;HRESULT hr = pFactory-QueryInterface(iid, ppv) ;pFactory-Release() ;return hr ;52STDAPI DllRegisterServer()return RegisterServer(g_hModule, CLSID_Component1, g_szFriendlyName

    39、, g_szVerIndProgID, g_szProgID) ;STDAPI DllUnregisterServer()return UnregisterServer(CLSID_Component1, g_szVerIndProgID, g_szProgID) ;53BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved)if (dwReason = DLL_PROCESS_ATTACH)g_hModule = hModule ;return TRUE ;54clientCOM LibDLLCFactoryCApIX-Fx()New CANew CFactoryIClassFactory:ReleaseIClassFactory:CreateInstance(IID_IX)CoGetClassObjectDllGetClassObject

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:高级软件工程06(COM基础:接口与实现).ppt
    链接地址:https://www.163wenku.com/p-2046209.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库