com学习3——包容

com 有两种重要的重用模型—包容和聚合。重用是现在软件开发中很看重的一部分。重用可以大大提高开发效率。com的这两个重用模型非常的经典。包容:有两个com对象,A,B,用户只知道com对象B的存在,并不知道com对象A的存在,而com对象B知道对象A的存在,并且com对象B中的一部分功能com对象A中已经实现,com对象B有这些功能函数但是不去自己实现这部分功能,而是去调用对象A的这部分功能,当用户调用对象B的这部分功能的时候,对象B就去调用对象A的这些功能,并将结果返回给用户。聚合:则重用的更彻底,对象B根本就不去实现那部分功能,连函数都没有,用户调用对象B的那部分功能的时候,对象B直接将对象A的那部分接口暴露给用户,用户直接调用到了对象A。但是对象A受对象B的控制。
包容:

 
聚合:
 

这次只介绍包容的实现,聚合下次再介绍。
 
包容程序实现:
com对象A:

 
接口:ISomefunction.h
 
#ifndef __ISomefunction_H__
#define __ISomefunction_H__
 
 
#include "Unknwn.h"
 
extern "C" const GUID IID_ISomefunction2;
 
class ISomefunction : public IUnknown
{
public:
virtual void __stdcall Somefunction() = 0;
};
 
#endif
 
 
 
 对象A:A.h
#ifndef __ISomefunction_H__
#include "ISomefunction.h"
 
//#endif
 
class CA : public ISomefunction
{
public:
CA();
~CA();
public:
virtual HRESULT __stdcall QueryInterface(const IID& iid,void **ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
 
public:
virtual void __stdcall Somefunction();
private:
int m_Ref;
};
 
#endif
 
A.cpp
#include "stdafx.h"
 
 
 
 
#include <comutil.h>
#include <stdio.h>
#include "objbase.h"
#include "olectl.h"
 
 
#include "A.h"
#include "Factory.h"
#include "Registry.h"
 
 
// {D45EAF90-D34A-4F89-98AD-2084765D711B}
extern "C" const GUID CLSID_A =
{ 0xd45eaf90, 0xd34a, 0x4f89, { 0x98, 0xad, 0x20, 0x84, 0x76, 0x5d, 0x71, 0x1b } };
extern "C" const GUID IID_ISomefunction2 =
{ 0xd45eaf92, 0xd34a, 0x4f89, { 0x98, 0xad, 0x20, 0x84, 0x76, 0x5d, 0x71, 0x1b } };
 
ULONG g_LockNumber = 0;
ULONG g_ANumber = 0;
HANDLE g_hModule;
 
 
 
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
g_hModule = hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
 
 
extern "C" HRESULT __stdcall DllGetClassObject(const CLSID& clsid,const IID& iid,void **ppv)
{
if(clsid == CLSID_A)
{
//CAFactory *pFactory = new CAFactory;
CAFactory *pFactory = new CAFactory;
if(pFactory == NULL) return E_OUTOFMEMORY;
 
HRESULT result = pFactory->QueryInterface(iid,ppv);
return result;
}
else return CLASS_E_CLASSNOTAVAILABLE;
}
 
extern "C" HRESULT __stdcall DllCanUnloadNow(void)
{
if((g_ANumber == 0) && (g_LockNumber == 0)) return S_OK;
else return S_FALSE;
}
 
extern "C" HRESULT __stdcall DllRegisterServer()
{
char szModule[1024];
DWORD dwResult = ::GetModuleFileName((HMODULE)g_hModule,szModule,1024);
if(dwResult == 0) return SELFREG_E_CLASS;
return RegisterServer(CLSID_A,szModule,"A.Object","A Component",NULL);
}
 
extern "C" HRESULT __stdcall DllUnregisterServer()
{
return UnregisterServer(CLSID_A,"A.Object",NULL);
}
 
CA::CA()
{
m_Ref = 0;
g_ANumber++;
}
 
CA::~CA()
{
 
}
 
HRESULT CA::QueryInterface(const IID& iid,void **ppv)
{
if(iid == IID_IUnknown)
{
*ppv = (ISomefunction *)this;
((ISomefunction *)(*ppv)) ->AddRef();
}
else if(iid == IID_ISomefunction2)
{
*ppv = (ISomefunction *)this;
((ISomefunction *)(*ppv)) ->AddRef();
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
 
ULONG CA::AddRef()
{
m_Ref++;
return (ULONG)m_Ref;
}
 
ULONG CA::Release()
{
m_Ref--;
if(m_Ref == 0)
{
g_ANumber--;
delete this;
return 0;
}
return (ULONG)m_Ref;
}
 
void CA::Somefunction()
{
printf("********************************\nCall function from A.\n********************************\n");
}
 
类厂:Factory.h
#ifndef __Factory_H__
#define __Factory_H__
 
#include "Unknwn.h"
 
 
class CAFactory : public IClassFactory
{
protected:
ULONG m_Ref;
public:
CAFactory();
~CAFactory();
 
 
virtual HRESULT __stdcall QueryInterface(const IID& iid,void **ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
public:
virtual HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter,const IID &iid,void **ppv);
virtual HRESULT __stdcall LockServer(BOOL);
};
 
#endif
 
Factory.cpp
#include "stdafx.h"
#include "Factory.h"
#include "A.h"
 
extern ULONG g_LockNumber;
extern ULONG g_ANumber;
 
 
CAFactory::CAFactory()
{
m_Ref = 0;
}
 
CAFactory::~CAFactory()
{
 
}
 
HRESULT CAFactory::QueryInterface(const IID& iid,void **ppv)
{
if(iid == IID_IUnknown)
{
*ppv = (IUnknown *)this;
((IUnknown*)(*ppv))->AddRef();
}
else if(iid == IID_IClassFactory)
{
*ppv = (IClassFactory*)this;
((IClassFactory*)(*ppv))->AddRef();
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
 
ULONG CAFactory::AddRef()
{
m_Ref++;
return (ULONG)m_Ref;
}
 
ULONG CAFactory::Release()
{
m_Ref--;
if(m_Ref == 0)
{
delete this;
return 0;
}
return (ULONG)m_Ref;
}
 
HRESULT CAFactory::CreateInstance(IUnknown *pUnknownOuter,const IID& iid,void **ppv)
{
CA *pObj;
HRESULT hr;
 
*ppv = NULL;
hr = E_OUTOFMEMORY;
if(NULL != pUnknownOuter) return CLASS_E_NOAGGREGATION;
 
pObj = new CA();
if(pObj == NULL) return hr;
 
hr = pObj->QueryInterface(iid,ppv);
if(hr != S_OK)
{
g_ANumber--;
delete pObj;
}
 
return hr;
}
 
HRESULT CAFactory::LockServer(BOOL bLock)
{
if(bLock) g_LockNumber++;
else g_LockNumber--;
 
return NOERROR;
}
Registry.h  Registry.cpp 和 .def文件跟之前的都是一样的,不再介绍。
 
com对象B
 

 
代码:
接口:ISomefunction.h
#ifndef __ISomefunction_H__
#define __ISomefunction_H__
 
#include "Unknwn.h"
 
extern "C" const GUID IID_ISomefunction;
 
class ISomefunction : public IUnknown
{
public:
virtual void __stdcall Somefunction() = 0;
};
 
#endif
 
IOtherfunction.h
#ifndef __IOtherfunction_H__
#define __IOtherfunction_H__
 
#include "Unknwn.h"
 
extern "C" const GUID IID_IOtherfunction;
 
class IOtherfunction : public IUnknown
{
public:
virtual void __stdcall Otherfunction() = 0;
};
 
#endif
 
对象B:B.h
#ifndef __ISomefunction_H__
#include "ISomefunction.h"
 
#endif
 
#ifndef __IOtherfunction_H__
#include "IOtherfunction.h"
 
#endif
 
class CB : public ISomefunction,public IOtherfunction
{
public:
CB();
~CB();
public:
virtual HRESULT __stdcall QueryInterface(const IID& iid,void **ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
 
public:
virtual void __stdcall Somefunction();
public:
virtual void __stdcall Otherfunction();
public:
HRESULT Init();
private:
int m_Ref;
ISomefunction *m_pSomefunction;
};
 
B.cpp
#include "stdafx.h"
 
 
 
#include <comutil.h>
#include <stdio.h>
#include "objbase.h"
#include "olectl.h"
 
#include "B.h"
#include "Factory.h"
#include "Registry.h"
 
 
extern "C" const GUID CLSID_A =
{ 0xd45eaf90, 0xd34a, 0x4f89, { 0x98, 0xad, 0x20, 0x84, 0x76, 0x5d, 0x71, 0x1b } };
 
 
extern "C" const GUID IID_ISomefunction2 =
{ 0xd45eaf92, 0xd34a, 0x4f89, { 0x98, 0xad, 0x20, 0x84, 0x76, 0x5d, 0x71, 0x1b } };
 
 
extern "C" const GUID CLSID_B =
{ 0x67c51297, 0xc0d7, 0x4c58, { 0x85, 0x23, 0x6c, 0xa6, 0x1b, 0x2c, 0xdd, 0x6c } };
 
extern "C" const GUID IID_ISomefunction =
{ 0x67c51298, 0xc0d7, 0x4c58, { 0x85, 0x23, 0x6c, 0xa6, 0x1b, 0x2c, 0xdd, 0x6c } };
 
extern "C" const GUID IID_IOtherfunction =
{ 0x67c51299, 0xc0d7, 0x4c58, { 0x85, 0x23, 0x6c, 0xa6, 0x1b, 0x2c, 0xdd, 0x6c } };
 
ULONG g_LockNumber = 0;
ULONG g_BNumber = 0;
HANDLE g_hModule;
 
 
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
g_hModule = hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
 
 
 
extern "C" HRESULT __stdcall DllGetClassObject(const CLSID& clsid,const IID& iid,void **ppv)
{
if(clsid == CLSID_B)
{
CBFactory *pFactory = new CBFactory;
if(pFactory == NULL) return E_OUTOFMEMORY;
 
HRESULT result = pFactory->QueryInterface(iid,ppv);
return result;
}
else return CLASS_E_CLASSNOTAVAILABLE;
}
 
extern "C" HRESULT __stdcall DllCanUnloadNow(void)
{
if((g_BNumber == 0) && (g_LockNumber == 0)) return S_OK;
else return S_FALSE;
}
 
extern "C" HRESULT __stdcall DllRegisterServer()
{
char szModule[1024];
DWORD dwResult = ::GetModuleFileName((HMODULE) g_hModule,szModule,1024);
if(dwResult == 0) return SELFREG_E_CLASS;
return RegisterServer(CLSID_B,szModule,"B.Object","B Component",NULL);
}
 
extern "C" HRESULT __stdcall DllUnregisterServer()
{
return UnregisterServer(CLSID_B,"B.Object",NULL);
}
 
 
CB::CB()
{
m_pSomefunction = NULL;
m_Ref = 0;
g_BNumber++;
}
 
CB::~CB()
{
if(m_pSomefunction != NULL) m_pSomefunction->Release();
}
 
HRESULT CB::Init()
{
HRESULT result = ::CoCreateInstance(CLSID_A,NULL,CLSCTX_INPROC_SERVER,IID_ISomefunction2,(void **)&m_pSomefunction);
if(FAILED(result)) return E_FAIL;
else return S_OK;
}
 
void CB::Somefunction()
{
m_pSomefunction->Somefunction();
}
 
void CB::Otherfunction()
{
printf("*************************************\nCall function from B.\n*************************************\n");
}
 
HRESULT CB::QueryInterface(const IID& iid,void **ppv)
{
if(iid == IID_IUnknown)
{
*ppv = (ISomefunction *)this;
((ISomefunction *)(*ppv))->AddRef();
}
else if(iid == IID_ISomefunction)
{
*ppv = (ISomefunction *)this;
((ISomefunction *)(*ppv))->AddRef();
}
else if(iid == IID_IOtherfunction)
{
*ppv = (IOtherfunction *)this;
((IOtherfunction *)(*ppv))->AddRef();
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
 
 
ULONG CB::AddRef()
{
m_Ref++;
return (ULONG)m_Ref;
}
 
ULONG CB::Release()
{
m_Ref--;
if(m_Ref == 0)
{
g_BNumber--;
delete this;
return 0;
}
return (ULONG)m_Ref;
}
 
类厂实现:Factory.h
#ifndef __Factory_H__
#define __Factory_H__
 
 
#include "Unknwn.h"
 
class CBFactory : public IClassFactory
{
protected:
ULONG m_Ref;
public:
CBFactory();
~CBFactory();
public:
virtual HRESULT __stdcall QueryInterface(const IID& iid,void **ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
 
public:
virtual HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter,const IID &iid,void **ppv);
virtual HRESULT __stdcall LockServer(BOOL);
};
 
#endif
 
Factory.cpp
#include "stdafx.h"
#include "Factory.h"
#include "B.h"
 
extern ULONG g_LockNumber;
extern ULONG g_BNumber;
 
 
CBFactory::CBFactory()
{
m_Ref = 0;
}
 
CBFactory::~CBFactory()
{
 
}
 
HRESULT CBFactory::QueryInterface(const IID& iid,void **ppv)
{
if(iid == IID_IUnknown)
{
*ppv = (IUnknown *)this;
((IUnknown *)(*ppv)) ->AddRef();
}
else if(iid == IID_IClassFactory)
{
*ppv = (IClassFactory *)this;
((IClassFactory *)(*ppv))->AddRef();
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
 
ULONG CBFactory::AddRef()
{
m_Ref++;
return (ULONG)m_Ref;
}
 
ULONG CBFactory::Release()
{
m_Ref--;
if(m_Ref == 0)
{
delete this;
return 0;
}
return (ULONG)m_Ref;
}
 
HRESULT CBFactory::CreateInstance(IUnknown *pUnknownOuter,const IID& iid,void **ppv)
{
CB *pObj;
HRESULT hr;
 
*ppv = NULL;
 
hr = E_OUTOFMEMORY;
if(pUnknownOuter != NULL) return CLASS_E_NOAGGREGATION;
 
pObj = new CB();
 
if(pObj == NULL) return hr;
pObj->Init();
hr = pObj->QueryInterface(iid,ppv);
if(hr != S_OK)
{
g_BNumber--;
delete pObj;
}
return hr;
}
 
HRESULT CBFactory::LockServer(BOOL bLock)
{
if(bLock) g_LockNumber++;
else g_LockNumber--;
 
return NOERROR;
}
解释:这里对象B中有个函数Init(),这个函数的作用是调用对象A的接口,将接口指针赋给
m_pSomefunction。对象B中的ISomefunction接口的功能是通过m_pSomefunction指针去调用对象A中的函数。
 
客户调用程序:
 

代码:IOtherfunction.h
#ifndef __IOtherfunction_H__
#define __IOtherfunction_H__
 
#include "Unknwn.h"
 
extern "C" const GUID IID_IOtherfunction;
 
class IOtherfunction : public IUnknown
{
public:
virtual void __stdcall Otherfunction() = 0;
};
 
#endif
 
ISomefunction.h
#ifndef __ISomefunction_H__
#define __ISomefunction_H__
 
#include "Unknwn.h"
 
extern "C" const GUID IID_ISomefunction;
 
class ISomefunction : public IUnknown
{
public:
virtual void __stdcall Somefunction() = 0;
};
 
#endif
 
call.cpp
#include "stdafx.h"
 
#include <stdio.h>
#include <comutil.h>
 
#include "ISomefunction.h"
#include "IOtherfunction.h"
 
 
extern "C" const GUID CLSID_B =
{ 0x67c51297, 0xc0d7, 0x4c58, { 0x85, 0x23, 0x6c, 0xa6, 0x1b, 0x2c, 0xdd, 0x6c } };
 
extern "C" const GUID IID_ISomefunction =
{ 0x67c51298, 0xc0d7, 0x4c58, { 0x85, 0x23, 0x6c, 0xa6, 0x1b, 0x2c, 0xdd, 0x6c } };
 
extern "C" const GUID IID_IOtherfunction =
{ 0x67c51299, 0xc0d7, 0x4c58, { 0x85, 0x23, 0x6c, 0xa6, 0x1b, 0x2c, 0xdd, 0x6c } };
 
 
/*extern "C" const GUID CLSID_B =
{0x54bf6567, 0x1007, 0x11d1, {0xb0, 0xaa, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
 
extern "C" const IID IID_Dictionary =
{ 0x54bf6568, 0x1007, 0x11d1,
{ 0xb0, 0xaa, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} } ;
 
extern "C" const IID IID_SpellCheck =
{ 0x54bf6569, 0x1007, 0x11d1,
{ 0xb0, 0xaa, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} } ;*/
 
 
 
 
 
int _tmain(int argc, _TCHAR* argv[])
{
 
IUnknown *pUnknown;
ISomefunction *pSomefunction;
IOtherfunction *pOtherfunction;
HRESULT hResult;
 
if(CoInitialize(NULL) != S_OK) printf("Initialize COM library failed!\n");
 
hResult = CoCreateInstance(CLSID_B,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,(void **)&pUnknown);
 
if(hResult != S_OK) printf("Create object failed!\n");
 
hResult = pUnknown->QueryInterface(IID_ISomefunction,(void **)&pSomefunction);
if(hResult != S_OK)
{
pUnknown->Release();
printf("QueryInterface ISomefunction failed!\n");
return 0;
}
 
pSomefunction->Somefunction();
 
hResult = pSomefunction->QueryInterface(IID_IOtherfunction,(void **)&pOtherfunction);
pOtherfunction->Release();
if(hResult != S_OK)
{
pUnknown->Release();
printf("QueryInterface IOtherfunction failed!\n");
return 0;
}
pOtherfunction->Otherfunction();
 
pOtherfunction->Release();
CoUninitialize();
int m;
scanf("%d",&m);
return 0;
}
 
运行结果:

转载于:https://www.cnblogs.com/waterhsu/archive/2012/05/02/com_contain.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值