ATL Internals 2ed复习.chapter 3.CComGITPtr
来源:互联网 发布:数据库int设置取值范围 编辑:程序博客网 时间:2024/06/06 04:24
Global Interface Table (GIT)提供了进程内interface共享机制,用户可以高效的在套间之间传递interface.
使用GIT通常需要下面几步:
1..源套间在GIT中注册interface,需要调用IGlobalInterfaceTable系统服务,取得一个cookie
HRESULT RegisterMyInterface(IMyInterface* pmi, DWORD* pdwCookie) { // this is usually a global IGlobalInterfaceTable* g_pGIT = NULL; HRESULT hr = ::CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void**)&g_pGIT);ATLASSERT(SUCCEEDED(hr));hr = g_pGIT->RegisterInterfaceInGlobal(pmi, __uuidof(pmi), pdwCookie);return hr;}
2..目标套间由这个cookie取得在该套间有效的interface
HRESULT ReadMyInterface(DWORD dwCookie) { // ... GIT pointer obtained elsewhere IMyInterface* pmi = NULL; hr = g_pGIT->GetInterfaceFromGlobal(dwCookie, __uuidof(pmi), (void**)&pmi); // use pmi as usual return hr;}
3..用完之后,使用IGlobalInterfaceTable::RevokeInterfaceFromGlobal销毁这个cookie
CComGITPtr
template <class T> class CComGITPtr { // ... DWORD m_dwCookie;};
m_dwCookie是唯一的state
构造函数:
CComGITPtr() ; CComGITPtr(T* p); CComGITPtr(const CComGITPtr& git); explicit CComGITPtr(DWORD dwCookie) ;
第一个m_dwCookie设置为0
第二个调用RegisterInterfaceInGlobal
第三个将会reregister,并将得到的cookie储存起来
最后一个在debug版本中将会验证cookie的正确性
CComGITPtr<T>& operator=(T* p) CComGITPtr<T>& operator=(const CComGITPtr<T>& git)CComGITPtr<T>& operator=(DWORD dwCookie)
做的事情一样
析构函数:
~CComGITPtr() { Revoke(); }
HRESULT Revoke() { HRESULT hr = S_OK; if (m_dwCookie != 0) { CComPtr<IGlobalInterfaceTable> spGIT; HRESULT hr = E_FAIL; hr = AtlGetGITPtr(&spGIT); ATLASSERT(spGIT != NULL); ATLASSERT(SUCCEEDED(hr)); if (FAILED(hr)) return hr; hr = spGIT->RevokeInterfaceFromGlobal(m_dwCookie); if (SUCCEEDED(hr)) m_dwCookie = 0; } return hr; }
HRESULT Attach(T* p) ; HRESULT Attach(DWORD dwCookie) ;
第一个函数将会首先释放旧的cookie,然后对新的指针进行注册
第二个也会首先释放旧的,然后将新的cookie赋值到数据
DWORD Detach() ;
返回内部cookie,将内部cookie置0
对于目标套间,用户可以使用
HRESULT CopyTo(T** pp) const
例子:
HRESULT ReadMyInterface(const CComGITPtr<IMyInterface>& git) { IMyInterface* pmi = NULL; HRESULT hr = git.CopyTo(&pmi); ATLASSERT(SUCCEEDED(hr)); //... use pmi as usual}
还应该防止多线程环境下的race condition,git会提前释放,此时应该使用WaitForSingleObject等手段:
void ThreadProc(void*); // forward declarationHRESULT RegisterInterfaceAndFork(IMyInterface* pmi) { CComGITPtr<IMyInterface> git(pmi); // interface registered // create worker thread and pass CComGITPtr instance ::_beginthread(ThreadProc, 0, &git);}void ThreadProc(void* pv){ CComGITPtr<IMyInterface>* pgit = (CComGITPtr<IMyInterface>*)pv; IMyInterface* pmi = NULL; HRESULT hr = pgit->CopyTo(&pmi); // ... do some work with pmi}
通常情况下,CComGITPtr不应该作为local变量
- ATL Internals 2ed复习.chapter 3.CComGITPtr
- ATL Internals 2ed复习.chapter 3.ATL Memory Managers
- ATL Internals 2ed复习.chapter 2
- ATL Internals 2ed复习.chapter 3.CComVariant
- ATL Internals 2ed复习.chapter 3.SAFEARRAY
- ATL Internals 2ed复习.chapter 3.CComSafeArray
- ATL Internals 2ed复习.chapter 3.CComPtr CComQIPtr
- ATL Internals 2ed复习.chapter 3.CAutoPtr
- ATL Internals 2ed复习.chapter 7.ATL Persistence implements
- ATL Internals 2ed复习.chapter 4.Thread
- ATL Internals 2ed复习.chapter 4.IUnknown
- ATL Internals 2ed复习.chapter 4.Creators
- ATL Internals 2ed复习.chapter 4.Debugging
- ATL Internals 2ed复习.chapter 5.COM Server review
- ATL Internals 2ed复习.chapter 5.Object Map
- ATL Internals 2ed复习.chapter 5.CAtlModule
- ATL Internals 2ed复习.chapter 6.Table driven QueryInterface
- ATL Internals 2ed复习.chapter 6.interface map tricks
- Linux的设备驱动程序应是一个内核模块
- paip.分成系统会员推广分销系统的设计
- Android activity生命周期讲解
- 《再见萤火虫》
- 设计模式(2) –工厂模式(Factory)
- ATL Internals 2ed复习.chapter 3.CComGITPtr
- C# 中的委托和事件
- POJ 3342 Party at Hali-Bula
- javaSE学习笔记7 多态
- 使用slmgr.vbs -rearm命令重置,提升需要提升特权 [此博文包含图片]
- 怎么样把中文版的Windows7改成英文版的Windows7
- 从“央视网”下载视频的方法
- 五笔打字教程
- malloc与new