ATL interface mapping macro detailed [6]

zhaozj2021-02-16  68

Fives. COM_INTERFACE_ENTRY_AGGREGATE (IID, PUNK)

This section will be introduced to the macro used to aggregate objects in ATL. Please refer to other reference books for the concept of gathering objects.

Let's take a look at this macro test now:

Class Cagg: Public IDispatchiMPL , PUBLIC ISUPPORTERRORINFO, PUBLIC CCOMOBJECTROOT, PUBLIC CCOMCOCLASS {.....};

CAGG is a gathering class, which does not differ from the general ATL component, just notice that do not join DECLARE_NO_AGGREGATABLE in its class definition.

class COuter: public CChainBase, public IDispatchImpl , public CComCoClass {HRESULT FinalConstruct (); void FinalRelease (); BEGIN_COM_MAP (COuter) COM_INTERFACE_ENTRY_AGGREGATE (IID_IAgg, m_pUnkAgg.p) END_COM_MAP () DECLARE_GET_CONTROLLING_UNKNOWN () Ccomptr m_punkagg;};

The COUTER contains the aggregated component CAGG, which contains several differences:

(1) Join Com_Interface_entry_aggregate (IID_IAGG, M_PUNKAGG.P) macro.

#define com_interface_entry_aggregate (IID, PUNK) / {& IID, / (DWORD) OFFSTOF (_CommapClass, punk), / _dlegate},

Offsetof We have seen in the previous section, you can guess it is the position in PUNK in the class. That is, M_Punkagg is in the position of the COUTER.

(2) Join the macro Declare_Get_Controlling_unkNown (), which is defined as:

#define declare_get_controlling_unknown () public: / virtual iUnknown * getControllingunknown () () () () () () () ()

We don't have to continue to go abroad, you can see this function will return to the component's iUnknown pointer from literally.

(3) Add a member variable in the COUTER: ccomptr m_punkagg; m_punkagg will be used to obtain an IUNKNOWN pointer to the aggregated component.

(4) Heavy loaded FinalConstruct, FinalRelease

HRESULT COuter :: FinalConstruct () {IUnknown * pUnkOuter = GetControllingUnknown (); HRESULT hRes = CoCreateInstance (CLSID_CAgg, pUnkOuter, CLSCTX_ALL, IID_IUnknown, (void **) & m_pUnkAgg); return hRes;} void COuter :: FinalRelease () {m_pUnkAgg .Release (); .....} FinalConstruct will be called after creating component couter, so you will create a gathering component here. In principle, the aggregation component can be created only when needed, but can also be created along with the components that contain it. There is no special place for the creation of the aggregation components, just pay attention to it will query the IUnknown pointer and return to m_punkagg. External components will operate the components via the M_PUnkagg operation. Also note that Punkouter as a parameter of CocreateInstance, which will cause CCOMAGGGOBJECT object, which contains a CCOMCONTAINEDOBJECT containing objects. With ccomcachedtearoff <> in the previous section, ccomaggobject is not derived from COUTER, so the real component object is not a ccomaggobject object, but it is included in the ccomcontainedObject object. The same PUNKOUTER will be the iUnknown pointer of ccomaggobject <>, and also calling its QueryInterface will turn the _ternalQueryinterface function (Oh, now I am guess now, see what I guess is right now.

Run Pouter-> queryinterface (IID_IAGG, (Void **) & PAGG1)

Function Stack 1:

9.atl :: atlinternalQueryinterface (...) 8.atl :: ccomobjectrootbase :: innalqueryinterface (...) 7.cagg :: _ internalQueryinterface (...) 6.atl :: ccomaggobject :: queryinterface. .) 5.atl :: ccomobjectrootbase :: _ delegate (...) 4.atl :: atlinternalQueryinterface (...) 3.atl :: ccomobjectrootbase :: interNalQueryinterface (...) 2.couter :: _ internalQueryinterface (. ..) 1.tl :: ccomobject :: queryinterface (...)

Explanation:

1-5: These steps have been called many times because of this macro definition using _Delegate, so CComObjectRootBase :: _ delegate (...).

Static HRESULT _DELEGATE (Void * PV, Refiid IID, Void ** PPVObject, DWORD DW) {HRESULT HRES = E_NOINTERFACE; IUNKNOWN * P = * (iUnknown **) ((DWORD) PV DW); if (p! = null HRES = P-> Queryinterface (IID, PPVObject); Return Hres;} The meaning of the second sentence we have seen in the previous section, the last result p = couter :: m_punkagg.

6: As we just expected, call now ccomaggobject :: queryinterface ()

STDMETHOD (REFIID IID, VOID ** PPVObject) {// If the query is iUnknown, then .... else hres = m_contained._internalQueryinterface (IID, PPVObject); Return HRES;}

Just as we expected, it will be handed over to it. (This code seems to be seen in the previous section, huh, huh)

7-9: Like the same section, it will be handed over to CAGG :: _ InternalQueryInterface (...), and the remaining work will be done by CAGG. The final returned pointer is actually the interface pointer of the CCOMCONTAINEDOBJECT component.

Run PAGG1-> Queryinterface (IID_IAGG, (Void **) & PAGG2)

Function Stack 2:

9.cagg :: _ InternalQueryinterface (...) 8.atl :: ccomaggobject :: queryinterface (...) 7.atl :: ccomobjectRootBase :: _ DELEGATE (...) 6.atl :: atlinternalQueryinterface ........................................................................................... ... CCOMOBJECTROOTBASE :: OuterQueryInterface (...) 1.tl :: ccomcontainedObject :: queryinterface (...)

Explanation:

1-9: Browse the entire stack, with the stack two of our previous section, because it is used to include objects. The role of the object has gone a proxy, he first handed the query to the external object (step 1, 2), when the external object is found to query the interface of the aggregated component (IAGG), The query is returned to the pointer to the aggregated component (M_PUnkagg, step 7, pay attention to this is not a real aggregation component), M_PUnkagg will hand over the query to the included object (step 8), including the object and give the query That's that the external object finds that the external object is found to query the interface of the external component, it is very simple, and directly queries. This prevents inconsistencies of external components and aggregated component query operations. Hey, the truth is really troublesome, but it is ok, it is very similar to the macro of the previous section. Related source code can be found in the previous section.

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

New Post(0)