COM学习笔记(十一 ):聚合的一个完整例子

//Cmpnt1.cpp -- Component1

#include <iostream.h>

#include <objbase.h>

#include "Iface.h"

#include "Registry.h"

void trace(const char* msg){cout<<"Component1; \t "<<msg<<endl;}

static HMODULE g_hModule = NULL;

static long g_cComponents = 0;

static long g_cServerLocks = 0;

const char g_szFriendlyName[] = "Inside COM,Component1";

const char g_szProgID[] = "InsideCOM.Cmpnt1_1";

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class CA : public IX{

public:

virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv);

virtual ULONG __stdcall AddRef();

virtual ULONG __stdcall Release();

virtual void __stdcall Fx(){cout<<"Fx"<<endl;}

virtual void __stdcall Fy(){m_pIY->Fy();}

CA();

~CA();

HRESULT __stdcall Init();

private:

long m_cRef;

IY* m_pIY;

IUnknown* m_pUnknownInner;

};

CA::CA():m_cRef(1),m_pUnknownInner(NULL){

InterlockedIncrement(&m_cComponents);

}

CA::~CA(){

InterlockedDecrement(&g_cComponents);

trace("Destroy self.");

m_cRef = 1;

IUnknown* pUnknownOuter = this;

pUnknownOuter->AddRef();

m_pIY->Release();

if(m_pUnknownInner != NULL){

m_pUnknownInner->Release();

}

HRESULT __stdcall CA::Init(){

IUnknown* pUnknownOuter = this;

trace("Create inner component.");

HRESULT hr = ::CoCreateInstance(CLSID_Component2,pUnknownOuter,CLSCTX_INPROC_SERVER,IID_IUnknown,(void**)&m_pUnknownInner);

if(FAILED(hr)){

trace("Could not create contained component.");

return E_FAIL;

}

hr = m_pUnknownInner->QueryInterface(IID_IY,(void**)&m_pIY);

if(FAILED(hr)){

trace("Inner component does not support interface IY.");

m_pUnknowInner->Release();

return E_FAIL;

}

pUnknownOuter->Release();

return S_OK;

}

HRESULT __stdcall CA::QueryInterface(const IID& iid,void** ppv){

if(iid == IID_IUnknown){

*ppv = static_cast<IUnknown*>(this);

}

else if(iid == IID_IX){

*ppv = static_cast<IX*>(this);

}

else if(iid == IID_IY){

trace("Return inner component's IY interface.");

return m_pUnknownInner->QueryInterface(iid,ppv);

//or *ppv = m_pIY;

}

else{

*ppv = NULL;

return E_NOINTERFACE;

}

reinterpret_cast<IUnknown*>(*ppv)->AddRef();

return S_OK;

}

ULONG __stdcall CA::AddRef(){

return InnerlockedIncrement(&m_cRef);

}

ULONG __stdcall CA::Release(){

id(InterlockedDecrement(&m_cRef) == 0){

delete this;

return 0;

}

return m_cRef;

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class CFactory : public IClassFactory{

public:

virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv);

virtual ULONG __stdcall AddRef();

virtual ULONG __stdcall Release();

virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter,const IID& iid,void** ppv);

virtual HRESULT __stdcall Lockserver(BOOL bLock);

CFactory() : m_cRef(1){}

~CFactory(){}

private:

long m_cRef;

};

HRESULT __stdcall CFactory::QueryInterface(const IID& iid,void** ppv){

IUnknown* pI;

if((iid == IID_IUnknown) || (iid == IID_IClassFactory)){

pI = static_cast<IClassFactory*>(this);

}

else{

*ppv = NULL;

return E_NOINTERFACE;

}

pI->AddRef();

*ppv = pI;

return S_OK;

}

ULONG CFactory::AddRef(){

return InterlockedIncrement(&m_cRef);

}

ULONG CFactory::Release(){

if(InterlockedDecrement(&m_cRef) == 0){

delete this;

return 0;

}

return m_cRef;

}

HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,void** ppv){

HRESULT hr = E_FAIL;

if(pUnknownOuter != NULL){

return CLASS_E_NOAGGREGATION;

}

CA* pA = new CA;

if(pA == NULL){

return E_OUTOFMEMORY;

}

hr = pA->Init(); //创建组件2,并请求IY接口

if(FAILED(hr)){

pA->Release();

return hr;

}

hr = pA->QueryInterface(iid,ppv);

pA->Release();

return hr;

}

HRESULT __stdcall CFactory::LockServer(BOOL bLock){

if(bLock){

InterlockedIncrement(&g_cServerLocks);

}

else{

InterlockedDecrement(&g_cServerLocks);

}

return S_OK;

}

STDAPI DllCanUnloadNow(){

if((g_cComponents == 0) && (g_cServerLocks == 0)){

return S_OK;

}

else{

return S_FALSE;

}

}

//Get class factory

STDAPI DllGetClassObject(const CLSID& clsid,void** ppv){

if(clsid != CLSID_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;

}

STDAPI DllRegisterServer(){

return RegisterServer(g_hModule,CLSID_Component1,g_szFriendlyName,g_szVerIndProgID,g_szProgID);

}

STDAPI DllUnregisterServer(){

return UnregisterServer(CLSID_Component1,g_szProgID);

}

BOOL APIENTRY DllMain(HANDLE hModule,DWORD dwReason,void* lpReserved){

if(dwReason == DLL_PROCESS_ATTACH){

g_hModule = hModule;

}

return TRUE;

}

//****************************************************************************************************************************************

//Cmpnt2.cpp -- Component2

#include <iostream.h>

#include <objbase.h>

#include "Iface.h"

#include "Registry.h"

void trace(const char* msg){cout<<"Component2: \t"<<msg<<endl;}

static HMODULE g_hModule = NULL;

static long g_cComponents = 0;

static long g_cServerLocks = 0;

const char g_szFriendlyName[]="Inside COM.Component2";

const char g_szVerIndProgID[] = "InsideCOM.Cmpnt2";

const char g_szProgID[] = "InsideCOM.Cmpnt2._1";

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class CB : public IY,public INondelegatingUnknown{

public:

virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv){

trace("Delegate QueryInterface.");

return m_pUnknownOuter->QueryInterface(iid,ppv);

}

virtual ULONG __stdcall AddRef(){

trace("Delegate AddRef.");

return m_pUnknownOuter->AddRef();

}

virtual ULONG __stdcall Release()

{

trace("Delegate Release");

return m_pUnknownOuter->Release();

}

virtual HRESULT __stdcall NondelegatingQueryInterface(const IID& iid,void** ppv);

virtual ULONG __stdcall NondelegatingAddRef();

virtual ULONG __stdcall NondelegatingRelease();

virtual void __stdcall Fy(){cout<<"Fy"<<endl;}

CB(IUnknown* m_pUnknownOuter);

~CB();

private:

long m_cRef;

IUnknown* m_pUnknownOuter;

};

HRESULT __stdcall CB::NondelegatingQueryInterface(const IID& iid,void** ppv){

if(iid == IID_IUnknown){

*ppv = static_cast<INondelegatingUnknown*>(this); //very important !!!

}

else if(iid == IID_IY){

*ppv = static_cast<IY*>(this);

}

else{

*ppv = NULL;

return E_NOINTERFACE;

}

reinterpret_cast<IUnknown*>(*ppv)->AddRef();

return S_OK;

}

ULONG __stdcall CB::NondelegatingAddRef(){

return InterlockedIncrement(&m_cRef);

}

ULONG __stdcall CB::NondelegatingRelease(){

if(InterlockedDecrement(&m_cRef = 0)){

delete this;

return 0;

}

return m_cRef;

}

CB::CB(IUnknown* pUnknownOuter) : m_cRef(1){

::InterlockedIncrement(&g_cComponents);

if(pUnknownOuter == NULL){

trace("不是代理未知接口;让我们委托给非代理未知接口吧");

m_pUnknownOuter = reinterpret_cast<IUnknown*>(static_cast<INondelegatingUnknown*>(this));

}

else{

trace("Aggregating; delegate to outer IUnknown.");

m_pUnknownOuter = pUnknownOuter;

}

}

CB::~CB(){

InterlockedDecrement(&g_cComponents);

trace("Destroy self");

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class CFactory : public IClassFactory{

public:

virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv );

virtual ULONG __stdcall AddRef();

virtual ULONG __stdcall Release();

virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter,void** ppv);

virtual HRESULT __stdcall LockServer(BOOL bLock);

CFactory() : m_cRef(1){}

~CFactory(){}

private:

long m_cRef;

};

HRESULT CFactory::QueryInterface(const IID& iid,void** ppv){

if((iid == IID_IUnknown) || (iid == IID_IClassFactory)){

*ppv = static_cast<IClassFactory*>(this);

}

else{

*ppv = NULL;

return E_NOINTERFACE;

}

reinterpret_cast<IUnknown*>(*ppv)->AddRef();

return S_OK;

}

ULONG _stdcall CFactory::AddRef(){

return InterlockedIncrement(&m_cRef);

}

ULONG _stdcall CFactory::Release(){

if(InterlockedDecrement(&m_cRef) == 0){

delete this;

return 0;

}

return m_cRef;

}

HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,void** ppv){

if((pUnknownOuter != NULL) && (iid != IID_IUnknown)){

return CLASS_E_NOAGGREGATION;

}

CB* pB = new CB(pUnknownOuter);

if(pB == NULL){

return E_OUTOFMEMORY;

}

HRESULT hr = pB->NondelegatingQueryInterface(iid,ppv);

pB->NondelegatingRelease();

return hr;

}

HRESULT CFactory::LockServer(BOOL bLock){

if(bLock){

InterlockedIncrement(&g_cServerLocks);

}

else{

InterlockedDecrement(&g_cServerLocks);

}

return S_OK;

}

STDAPI DllCanUnloadNow(){

if((g_cComponents == 0) && (g_cServerLocks == 0)){

return S_OK;

}

else{

return S_FALSE;

}

}

STDAPI DllGetClassObject(const CLSID& clsid,void** ppv){

if(clsid != CLSID_Component2){

return CLASS_E_CLASSNOTAVAILABLE;

}

CFactory* pFactory = new CFactory;

if(pFactory == NULL){

return E_OUTOFMEMORY;

}

HRESULT hr = pFactory ->QueryInterface(iid,ppv);

pFactory->Release();

return hr;

}

STDAPI DllRegisterServer(){

return RegisterServer(g_hModule,CLSID_Component2,g_szProgID);

}

STDAPI DllUnregisterServer(){

return UnregisterServer(CLSID_Component2,g_szProgID);

}

BOOL API ENTRY DllMain(HANDLE hModule,void* lpReserved){

if(dwReason == DLL_PROCESS_ATTACH){

g_hModule = hModule;

}

return TRUE;

}

此例中,外部组件只是聚合了内部组件实现的一个接口,客户能够访问的内部组件将只有IY。

当外部组件需要聚合内部组件实现的多个接口时:

避免使用盲目聚合,为避免冲突,有两种方法:其一,元接口。其二,将外部组件和客户或外部组件和内部组件作为匹配对来实现。

组件的内部状态信息:

COM中的所有功能都是通过借口来实现的。因此,为提供内部状态信息,可以加上一个新的接口。此接口可以给外部组件提供一些状态信息,帮助开发人员实现对组件的定制





版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


什么是设计模式一套被反复使用、多数人知晓的、经过分类编目的、代码 设计经验 的总结;使用设计模式是为了 可重用 代码、让代码 更容易 被他人理解、保证代码 可靠性;设计模式使代码编制  真正工程化;设计模式使软件工程的 基石脉络, 如同大厦的结构一样;并不直接用来完成代码的编写,而是 描述 在各种不同情况下,要怎么解决问题的一种方案;能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免引
单一职责原则定义(Single Responsibility Principle,SRP)一个对象应该只包含 单一的职责,并且该职责被完整地封装在一个类中。Every  Object should have  a single responsibility, and that responsibility should be entirely encapsulated by t
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强烈推荐。原文截图*************************************************************************************************************************原文文本************
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的一些设计问题,总结出来的一套通用的解决方案。
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
外观模式又叫门面模式,它提供了一个统一的(高层)接口,用来访问子系统中的一群接口,使得子系统更容易使用。
单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。
组合模式可以将对象组合成树形结构来表示“整体-部分”的层次结构,使得客户可以用一致的方式处理个别对象和对象组合。
装饰者模式能够更灵活的,动态的给对象添加其它功能,而不需要修改任何现有的底层代码。
观察者模式(Observer Design Pattern)定义了对象之间的一对多依赖,当对象状态改变的时候,所有依赖者都会自动收到通知。
代理模式为对象提供一个代理,来控制对该对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来给原始类附加功能。
工厂模式(Factory Design Pattern)可细分为三种,分别是简单工厂,工厂方法和抽象工厂,它们都是为了更好的创建对象。
状态模式允许对象在内部状态改变时,改变它的行为,对象看起来好像改变了它的类。
命令模式将请求封装为对象,能够支持请求的排队执行、记录日志、撤销等功能。
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 基本介绍 **意图:**在不破坏封装性的前提下,捕获一个对象的内部状态,并在该
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为
享元模式(Flyweight Pattern)(轻量级)(共享元素)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结