ATL Internals 2ed复习.chapter 6.Table driven QueryInterface
来源:互联网 发布:知乎为什么也叫b乎 编辑:程序博客网 时间:2024/06/05 15:25
The Raw Interface Map
ATL实现QueryInterface的方法是调用CComObjectRootBase::InternalQueryInterface():
static HRESULT WINAPI CComObjectRootBase::InternalQueryInterface( void* pThis, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject) { // First entry in the com map should be a simple map entry ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY); HRESULT hRes = AtlInternalQueryInterface(pThis, pEntries, iid, ppvObject); return hRes; }
ATL_INTMAP_ENTRY
其中涉及到ATL_INTMAP_ENTRY,作为数组传递给InternalQueryInterface():
struct _ATL_INTMAP_ENTRY { const IID* piid; // the interface id (IID) DWORD_PTR dw; _ATL_CREATORARGFUNC* pFunc; //NULL:end, 1:offset, n:ptr};
其中_ATL_CREATORARGFUNC的定义为:
typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)( void* pv, // Object's this pointer REFIID riid, // IID of requested interface LPVOID* ppv, // Storage for returned interface pointer DWORD_PTR dw); // dw from the interface map entry
AtlInternalQueryInterface
作为一个全局函数,AtlInternalQueryInterface()的作用是遍历interface map,找出匹配的iid,返回指针
ATLINLINE ATLAPI AtlInternalQueryInterface( void* pThis, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject) { ATLASSERT(pThis != NULL); ATLASSERT(pEntries!= NULL); if(pThis == NULL || pEntries == NULL) return E_INVALIDARG ; // First entry in the com map should be a simple map entry ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY); if (ppvObject == NULL) return E_POINTER; *ppvObject = NULL; if (InlineIsEqualUnknown(iid)) { // use first interface IUnknown* pUnk=(IUnknown*)((INT_PTR)pThis+pEntries->dw); pUnk->AddRef(); *ppvObject = pUnk; return S_OK; } while (pEntries->pFunc != NULL) { BOOL bBlind = (pEntries->piid == NULL); if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid)) { if (pEntries->pFunc == _ATL_SIMPLEMAPENTRY) { //offset ATLASSERT(!bBlind); IUnknown* pUnk = (IUnknown*)((INT_PTR) pThis+pEntries->dw); pUnk->AddRef(); *ppvObject = pUnk; return S_OK; } else { //actual function call HRESULT hRes = pEntries->pFunc(pThis, iid, ppvObject, pEntries->dw); if (hRes == S_OK || (!bBlind && FAILED(hRes))) return hRes; } } pEntries++; } return E_NOINTERFACE; }
注意,interface map第一项一定要是_ATL_SIMPLEMAPENTRY类型,否则会assert。
如果查询IUnknown,该函数直接返回第一项
如果pEntries->piid==NULL,将会调用pFunc,在COM_INTERFACE_ENTRY_XXX_BLIND将会用到这一特性。- ATL Internals 2ed复习.chapter 6.Table driven QueryInterface
- ATL Internals 2ed复习.chapter 2
- ATL Internals 2ed复习.chapter 6.interface map tricks
- ATL Internals 2ed复习.chapter 3.ATL Memory Managers
- ATL Internals 2ed复习.chapter 7.ATL Persistence implements
- 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.CComGITPtr
- ATL Internals 2ed复习.chapter 3.CAutoPtr
- 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
- js 表格相关操作代码
- 关于Struts2拦截Flex请求的问题
- AndroidManifest.xml文件解析
- eclipse中新建struts工程
- Struts2,Hibernate,Spring自定义配置文件路径
- ATL Internals 2ed复习.chapter 6.Table driven QueryInterface
- Flex中加载gif图片
- 判断一个数的所有因数的个数是偶数还是奇数
- C++中的虚基类以及构造函数解析
- C++程序设计-第七周上机实践项目
- Win7部署asp.net网站,问题逐个突破<一>---Win7 IIS 部署网站,同局域网中电脑无法访问解决方案
- Web相关Cache介绍
- 用ExternalInterface实现Flex与外部容器交互
- 火狐下firebug调试工具的使用