COM 对象聚合
|
无论是对象聚合或是对象包容,其作用都是组件的复用,使用环境是这样的,有组件some对象和other对象,我们暴露出来的是some对象,现在需求改变了,some要加入新 的功能,而该功能已经被other组件对象实现,而且完全不需要修改,在这种情况下,使用对象聚合,即,首先获得Isome的接口,使用其功能,在Isome接口中使用 QueryInterface函数,获得Iother接口,进而复用其功能。现在说下,在WIN7+VS2010的编程环境下: 外部对象声明: class ATL_NO_VTABLE Csome :
public CComObjectRootEx<CComSingleThreadModel>,public CComCoClass<Csome,&CLSID_some>,public IDispatchImpl<Isome,&IID_Isome,&LIBID_neoLib,/*wMajor =*/ 1,/*wMinor =*/ 0>
{
public:
Csome()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_SOME)
DECLARE_GET_CONTROLLING_UNKNOWN() //这点是自己添加的,至于其含义,请自行百度...
BEGIN_COM_MAP(Csome)
COM_INTERFACE_ENTRY(Isome)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pInner.p)
//聚合B组件的IB接口,也可以使用COM_INTERFACE_ENTRY_AUTOAGGREGATE宏,则不需要在FinalConstruct
//函数中创建B对象。
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
HRESULT hr = S_OK;
if(!m_pInner) //此处主要用于创建内部对象,并传递进去Isome的指针
hr = ::CoCreateInstance(CLSID_other,GetControllingUnknown(),CLSCTX_INPROC_SERVER,IID_IUnknown,(void**)&m_pInner);
return hr;
}
void FinalRelease()
{
m_pInner.Release();
}
public:
CComPtr<IUnknown>m_pInner;//这儿使用智能指针
STDMETHOD (someMsg)(BSTR var)//该函数用于测试
{
MessageBox(NULL,var,L"SOME",0);
return S_OK;
}
};
OBJECT_ENTRY_AUTO(__uuidof(some),Csome)
内部对象的实现: class ATL_NO_VTABLE Cother :
public CComObjectRootEx,public CComCoClass,public IDispatchImpl
{
public:
Cother()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_OTHER)
DECLARE_AGGREGATABLE(Cother); //声明组件Cother可以被聚合,这也是自己添加的
BEGIN_COM_MAP(Cother)
COM_INTERFACE_ENTRY(Iother)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
public:
STDMETHOD(otherMsg)(BSTR var)
{
MessageBox(NULL,L"other",0);
return S_OK;
}
};
OBJECT_ENTRY_AUTO(__uuidof(other),Cother)
测试文件:
#include "stdafx.h"
#include
#include
using namespace std;
#import"D:projectneoDebugneo.dll" no_namespace
#include"D:projectneoneoneo_i.c"
int _tmain(int argc,_TCHAR* argv[])
{
::CoInitialize(NULL);
IsomePtr somePtr;
HRESULT hr=somePtr.CreateInstance(__uuidof(some));
Isome* psome=NULL;
hr=somePtr.QueryInterface(IID_Isome,(void**)&psome);
if(S_OK!=hr)
{
return 0;
}
psome->someMsg(L"some have a try");
Iother* pother=NULL;
hr=psome->QueryInterface(IID_Iother,(void**)&pother);
if(S_OK!=hr)
{
return 0;
}
pother->otherMsg(L"other have a try");
pother->QueryInterface(IID_Isome,(void**)&psome);
psome->someMsg(L"DSHAIDA");
somePtr.Release();
::CoUninitialize ();
return 0;
}
笔者在进行测试过程中遇到了两个问题,很是诡异, 1.是在CreateInstance中返回没有注册类,可是本来不用regsvr32的,但是,regsvr32注册过后也不行, 解决方案是: 最后发现是在FinalStruct函数出现了错误。 2.是IID_Isome中出现了连接错误无法解析的外部符号IID_(这里是开发者自己写的接口名称), 解决方案是: 不再使用#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const type name = {l,{b1,b8}} MIDL_DEFINE_GUID(IID,IID_Isome,0xDB21B3C7,0xF4EC,0x4152,0x9B,0xFB,0xE5,0xC3,0xB8,0x4D,0x91); 而是加入了#include"D:projectneoneoneo_i.c"定义文件,最后测试成功!一天啊同学们.... (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
