COM技术内幕--编程工作的简化
2016-12-19 13:18
295 查看
智能接口指针:
1)什么是智能指针
一个智能指针实际上就是一个重载了操作符->的类。
智能接口指针类包含指向另外一个对对象的指针。当用户调用智能指针上的->操作符时,智能指针把此调用转发给它所包含的所指对象。智能接口指针中所包含的指针将是指向一个接口的。
智能接口指针IPtr的实现:
class CFoo
{
public:
virtual void Bar();
};
class CFooPointer
{
public:
CFooPointer(CFoo* p){m_p=p;}
CFoo* operator->(){return m_p;}
private:
CFoo* m_p;
};
void Funky(CFoo* pFoo)
{
CFooPointer spFoo(pFoo);
spFoo->Bar();
}
/////////////////////
智能接口指针可以将函数调用转发给相应类中所包含的接口指针
接口指针类的实现:
template <class T,const IID* piid> class IPtr
{
public:
IPtr()
{
m_pI = NULL;
}
IPtr(T* lp)
{
m_pI = lp;
if (m_pI != NULL)
{
m_pI->AddRef();
}
}
IPtr(IUnknown*pI)
{
m_pI = NULL;
if (pI != NULL)
{
pI->QueryInterface(*piid,(void**)&m_pI);
}
}
~IPtr()
{
Release();
}
void Release()
{
if (m_pI != NULL)
{
T* pOld = m_pI;
m_pI = NULL;
pOld->Release();
}
}
operator T*(){return m_pI;}
T& operator *(){assert(m_pI != NULL);return *m_pI;}
T** operator&(){assert(m_pI != NULL);return &m_pI;}
T* operator->(){assert(m_pI != NULL);return m_pI;}
T* operator = (IUnknown*pI)
{
IUnknown* pOld = m_pI;
m_pI = NULL;
if (pI != NULL)
{
HRESULT hr = pI->QueryInterface(*piid,(void**)&m_pI);
assert(SUCCEEDED(hr)&&(m_pI!=NULL));
}
if (pOld != NULL)
{
pOld->Release();
}
return m_pI;
}
BOOL operator !(){return (m_pI == NULL)?TRUE:FALSE;}
operator BOOL()const
{
return (m_pI != NULL)?TRUE:FALSE;
}
const IID& iid(){return *piid;}
private:
T* m_pI;
};
接口指针的使用:
void main()
{
IPtr<IX,&IID_IX>spIX;
HRESULT hr = ::CoCreateInstance(CLSID_COMPONENT1,
NULL,
CLSCTX_ALL,
spIX.iid(),
(void**)&spIX);
if(SUCCEEDED(hr))
{
spIX->Fx();
}
}
上面对于CoCreateInstance的调用并不是类型安全的,但可以通过在IPtr模板中定义另外一个函数以使之成为类型安全的。
HRESULT CreateInstance(const CLSID& clsid,IUnknown* pI,DWORD clsctx)
{
Release();
return CoCreateInstance(clsid,pI,clsctx,*piid,(void**)&m_pI);
}
对于IPtr上可按如下方式使用:
IPtr<IX,&IID_IX> spIX;
HRESULT hr = spIX.CreateInstance(CLSID_Component1,NULL,CLSCTX_INPROC_SERVER);
服务器端的简化:
ActiveX模板库
使用CUnknown和CFactory并不是简化COM组件实现的唯一方法。另外一种方法是使用ActiveX模板库(ATL)。此库给COM组件的建立提供了一个可利用的模板类集合。ATL中的类所支持的功能是此处我们给出的CFactory和CUnknown的一个超集。
1)什么是智能指针
一个智能指针实际上就是一个重载了操作符->的类。
智能接口指针类包含指向另外一个对对象的指针。当用户调用智能指针上的->操作符时,智能指针把此调用转发给它所包含的所指对象。智能接口指针中所包含的指针将是指向一个接口的。
智能接口指针IPtr的实现:
class CFoo
{
public:
virtual void Bar();
};
class CFooPointer
{
public:
CFooPointer(CFoo* p){m_p=p;}
CFoo* operator->(){return m_p;}
private:
CFoo* m_p;
};
void Funky(CFoo* pFoo)
{
CFooPointer spFoo(pFoo);
spFoo->Bar();
}
/////////////////////
智能接口指针可以将函数调用转发给相应类中所包含的接口指针
接口指针类的实现:
template <class T,const IID* piid> class IPtr
{
public:
IPtr()
{
m_pI = NULL;
}
IPtr(T* lp)
{
m_pI = lp;
if (m_pI != NULL)
{
m_pI->AddRef();
}
}
IPtr(IUnknown*pI)
{
m_pI = NULL;
if (pI != NULL)
{
pI->QueryInterface(*piid,(void**)&m_pI);
}
}
~IPtr()
{
Release();
}
void Release()
{
if (m_pI != NULL)
{
T* pOld = m_pI;
m_pI = NULL;
pOld->Release();
}
}
operator T*(){return m_pI;}
T& operator *(){assert(m_pI != NULL);return *m_pI;}
T** operator&(){assert(m_pI != NULL);return &m_pI;}
T* operator->(){assert(m_pI != NULL);return m_pI;}
T* operator = (IUnknown*pI)
{
IUnknown* pOld = m_pI;
m_pI = NULL;
if (pI != NULL)
{
HRESULT hr = pI->QueryInterface(*piid,(void**)&m_pI);
assert(SUCCEEDED(hr)&&(m_pI!=NULL));
}
if (pOld != NULL)
{
pOld->Release();
}
return m_pI;
}
BOOL operator !(){return (m_pI == NULL)?TRUE:FALSE;}
operator BOOL()const
{
return (m_pI != NULL)?TRUE:FALSE;
}
const IID& iid(){return *piid;}
private:
T* m_pI;
};
接口指针的使用:
void main()
{
IPtr<IX,&IID_IX>spIX;
HRESULT hr = ::CoCreateInstance(CLSID_COMPONENT1,
NULL,
CLSCTX_ALL,
spIX.iid(),
(void**)&spIX);
if(SUCCEEDED(hr))
{
spIX->Fx();
}
}
上面对于CoCreateInstance的调用并不是类型安全的,但可以通过在IPtr模板中定义另外一个函数以使之成为类型安全的。
HRESULT CreateInstance(const CLSID& clsid,IUnknown* pI,DWORD clsctx)
{
Release();
return CoCreateInstance(clsid,pI,clsctx,*piid,(void**)&m_pI);
}
对于IPtr上可按如下方式使用:
IPtr<IX,&IID_IX> spIX;
HRESULT hr = spIX.CreateInstance(CLSID_Component1,NULL,CLSCTX_INPROC_SERVER);
服务器端的简化:
ActiveX模板库
使用CUnknown和CFactory并不是简化COM组件实现的唯一方法。另外一种方法是使用ActiveX模板库(ATL)。此库给COM组件的建立提供了一个可利用的模板类集合。ATL中的类所支持的功能是此处我们给出的CFactory和CUnknown的一个超集。
相关文章推荐
- COM技术内幕第九章笔记-编程工作的简化
- COM---编程工作的简化
- COM 技术内幕学习之九 (简化程序编写)
- COM 组件技术内幕之四 (引用计数)
- COM技术内幕-读书笔记-系列之零
- 关于一个VC++6.0技术内幕的COM错误问题,错误信息:error C2504: 'IMotion' : base class undefined
- COM技术内幕摘要
- COM技术内幕-读书笔记-系列之五
- COM 技术内幕学习之八(包容和聚合)
- COM 技术内幕学习之二 (接口)
- COM技术内幕-读书笔记-系列之三
- ***求书***COM技术内幕
- 包容和聚合(COM技术内幕笔记五)
- COM技术内幕中聚合的实现
- COM组件的类厂(COM技术内幕笔记之四)
- COM 技术内幕学习之六 (HRESULT,GUID)
- inside com(com技术内幕)重读-摘录
- 动态链接库实现COM(COM技术内幕笔记之二)
- COM技术内幕学习笔记(2)
- com技术内幕读书笔记2