ATL Study Notes (4): COM interface ing table

Source: Internet
Author: User

Ccomobjectrootobjectbase provides an internal implementation of interface query in table-driven mode, that is, internalqueryinterface (). Therefore, when creating an ATL-Based Com class, you must create a ing table containing all the Implemented interfaces.


1. begin_com_map, end_com_map, com_interface_entry, and com_interface_entry2 macros

ATL provides

Begin_com_map,

End_com_map,

Com_interface_entry

Com_interface_entry2

These four macros are used to create an interface ing table.

 

Assume that a class cclassa inherits the iinta and iintb interfaces, the interface ing table of this class is created as follows:

Class cclassa: Public ccomobjectrootex <ccomsinglethreadmode>

{

Begin_com_map (cclassa)

Com_interface_entry (iinta)

Com_interface_entry (iintb)

End_com_map ()

......

};

While, when cclassb inherits iintc and iintd, both iintc and iintd inherit from the idispatch interface. At this time, if the client program is querying the idispatch interface, the idispatch interface pointer returned by QueryInterface cannot determine whether it belongs to iintc or iintd. In this case, you need to specify the default point of the idispatch interface pointer. The com_interface_entry2 () macro is used to complete this function. The following code points the request to the idispatch interface to the iintd idispatch interface pointer by default.

Class cclassb: Public ccomobjectrootex <ccomsinglethreadmode>

{

Begin_com_map (cclassa)

Com_interface_entry (iintc)

Com_interface_entry (iintd)

Com_interface_entry2 (idispatch, iintd)

End_com_map ()

......

};

 

2. Implementation and functions of the interface ing table

You can get the following code by using the macro extension in cclassb, which is slightly simplified:

Class cclassb: Public ccomobjectrootex <ccomsinglethreadmode>

{
// Begin_com_map (cclassb)

Public:

Typedef cclassb _ commapclass;

Static hresult _ cache (void * PV, refiid IID, void * ppvobject, dword_ptr DW)

{

_ Commapclass * P = (_ commapclass *) PV;

P-> lock ();

Hresult hres = ccomobjectrootbase: _ cache (PV, IID, ppvobject, DW );

P-> unlock ();

Return hres;

}



Iunknown * _ getrawunknown ()

{Return (iunknown *) (int_ptr) This ++ _ getentries ()-> DW );}



Hresult _ internalqueryinterface (refiid IID, void ** ppvobj)

{Return internalqueryinterface (this, _ getentries (), IID, ppvobj );}



Const static ATL: _ atl_intmap_entry * _ getentries ()

{

Static const ATL: _ atl_intmap_entry _ entries [] =

{
// Com_interface_entry (iintc)

{& _ Atl_iidof (iintc ),

Offsetofclass (iintc, _ commapclass ),

_ Atl_simplemapentry

},
// Com_interface_entry (iintd)

{& _ Atl_iidof (iintd ),

Offsetofclass (iintd, _ commapclass ),

_ Atl_simplemapentry

},
// Com_interface_entry2 (idispatch, iintd)

{& _ Atl_iidof (iintd ),

Reinterpret_cast <dword_ptr> (static_cast <idispatch *> (

Static_cast <iintd *> (reinterpret_cast <_ commapclass *> (8)-8,

_ Atl_simplemapentry

},
// End_com_map ()

{Null, 0, 0}

};

Return & _ entries;

}

Virtual ulong addref () = 0;

Virtual ulong release () = 0;

Hresult QueryInterface (refiid, void *) = 0; (# how to add the order of the three functions ?)

};

 

According to the above Code, the key to the role of begin_com_map () and other macros is to provide a static _ getentries () method to obtain a static COM interface ing table created in this method. Where, when the base class (or interface) is the parent class (or interface) of the derived class (or interface), The offsetofclass (base, derived) macro is used to return the base interface (or Class) the pointer offset value in the class relative to the derived pointer in the virtual table of the derived class. The _ atl_simplemapentry constant represents the second member DW of the _ atl_intmap_entry structure, which represents the offset value between the base and the derived pointer. The main difference between com_interface_entry2 and com_interface_entry is the calculation of the Offset Value.

In addition, the end_com_map () macro declares the addref () and release () Methods of iunknown as pure virtual functions. From this we can see that the iunknown interface method is destined to have the subclass implementation of this class.


3. Conclusion

Each Atl-based COM object must first create a static interface ing table, which is created by the begin_com_map, end_com_map, com_interface_entry, and com_interface_entry2 macros. They create an interface ing table and an interface ing table to obtain functions, and declare iunknown methods as pure virtual functions, which will be implemented by their derived classes.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.