ATL interface mapping macro detailed [7]

zhaozj2021-02-16  75

Six, com_interface_entry_aggregate_blind Part ITL RROR COMMAP Previous We talked about com_interface_entry_aggregate, the macro to be introduced in this section is very similar.

#DEfine COM_ITERFACE_ENTRY_AGGREGATE_BLIND (PUNK) / {NULL, / (DWORD) Offsetof (_Commapclass, punk), / _dlegate},

As can be seen from the definition, it is the only difference between the introduction to the previous section is that it does not specify the interface ID! !

So the first item in its definition is NULL.

This macro is used in the same way as our com_interface_entry_aggregate. You can refer to the previous section and the ATL routine COMMAP.

Let's take a look at the related code in atlinternalQueryInterface ().

ATLINLINE ATLAPI AtlInternalQueryInterface (void * pThis, const _ATL_INTMAP_ENTRY * pEntries, REFIID iid, void ** ppvObject) {// If IUnknown, .... while (pEntries-> pFunc! = NULL) {BOOL bBlind = (pEntries-> PIID == NULL); if (bblind || inlineisequalguid (* (pentries-> piid), IID)) {if (pentries-> pfunc == _tl_simplemapentry) // offset {atlassert (! bblind); iUnknown * punk = Iunknown *) ((int) PTHIS PENTRIES-> DW); punk-> addref (); * ppVObject = punk; return s_ok;} else {hresult hres = pentries-> pfunc (pthis, iid, ppvobject, pentries-> DW); if (hres == s_ok || (! BBLIND && Failed (HRES))) Return HRES;}}}}}}} Return E_NOINTERFACE;} Note Variable BBLIND: BOOL BBLIND = (Pentries-> PIID == NULL);

If the interface ID is not specified, continue to perform the following operations, it can be seen that even if the IID we need, _Delegate will be performed.

As can be seen from the above, this macro is suitable for a case where a gathering component has multiple interfaces, so as long as it is querying the interface of this aggregation component, it will enter the _dlegate function. But special attention is the location of this macro! ! For example, if this is the order:

Begin_COM_MAP COM_INTERFACE_ENTRY_AGGREGATE_BLIND (m_punkagblind.p) COM_INTERFACE_ENTRY (IOUTER) End_com_map When Query IOUTER interface, it will be wrong! ! !

Seven, com_interface_entry_autoaggregate (IID, PUNK, CLSID) First look at this macro definition:

#define COM_INTERFACE_ENTRY_AUTOAGGREGATE (iid, punk, clsid) / {& iid, / (DWORD) & _ CComCacheData , / (DWORD) offsetof (_ComMapClass, punk) /> :: data, / _Cache},

Let's take a look at its typical usage:

class CAutoAgg: public IDispatchImpl , public ISupportErrorInfo, public CComObjectRoot, public CComCoClass {......};

With the general components and no numbers.

class COuter: public CChainBase, public IDispatchImpl, public CComCoClass {BEGIN_COM_MAP (COuter) COM_INTERFACE_ENTRY_AUTOAGGREGATE (IID_IAutoAgg, m_pUnkAutoAgg.p, CLSID_CAutoAgg) END_COM_MAP () CComPtr m_pUnkAutoAgg;};

Unlike the macro COM_ITERFACE_ENTRY_AGGREGRATE (_), COUTER does not have to create a gathering component in FinalConstruct. External components will automatically create aggregated components! ! !

1.

Template _tl_cachedata _ccomcachedata :: data = {dwvar, creator :: creat einstance};

2.

static HRESULT WINAPI _Cache (void * pv, REFIID iid, void ** ppvObject, DWORD dw) {HRESULT hRes = E_NOINTERFACE; _ATL_CACHEDATA * pcd = (_ATL_CACHEDATA *) dw; IUnknown ** pp = (IUnknown **) ((DWORD) PV PCD-> dwoffsetvar; if (* pp == null) hres = pcd-> PFUNC (PV, IID_IUNKNOWN, (VOID **) PP); if (* pp! = null) hres = (* pp) - > Queryinterface (IID, ppvobject); return hres;}

3.

template class CComAggregateCreator {public: static HRESULT WINAPI CreateInstance (void * pv, REFIID / * riid * /, LPVOID * ppv) {ATLASSERT (* ppv == NULL); ATLASSERT (pv =! NULL); T * p = (t *) PV; Return CocreateInstance (* PCLSID, P-> getControllingunkNown () (), clsctx_all, iid_iunknown, ppv);}}; because _cache, _ccomcachedata, ccomaggregatecreator these classes and functions we I have seen it in front or have seen it, so I will not talk more. In short, we can see that if m_punkautoagg.p does not directly query the flight, create a gathering component.

Compared with the macro COM_INTERFACE_ENTRY_AGGREGATE, this macro seems to be better, only when it is needed, it is easier to use.

Eight, com_interface_entry_autoaggregate_blind (Punk, CLSID)

Take a look at its definition:

#define COM_INTERFACE_ENTRY_AUTOAGGREGATE_BLIND (punk, clsid) / {NULL, / (DWORD) & _ CComCacheData , / (DWORD) offsetof (_ComMapClass, punk) /> :: data, / _Cache},

Oh, this macro combines the characteristics of com_interface_entry_autoaggregate () and COM_ITERFACE_ENTRY_AGGREGATE_BLIND (), which can automatically create multiple interfaces in the aggregated component. No longer! !

转载请注明原文地址:https://www.9cbs.com/read-15315.html

New Post(0)