views:

64

answers:

1

Seems like both COM_INTERFACE_ENTRY_IID and COM_INTERFACE_ENTRY2_IID are for the case when the class is derived from two or more classes each derived from a common interface. Like this:

class CMyClass : public IPersistFile, public IPersistStream {

};

(both IPersistStream and IPersistFile derive from IPersist).

Looks like I'm free to include either

COM_INTERFACE_ENTRY_IID( __uuidof( IPersist ), IPersistFile )

or

COM_INTERFACE_ENTRY2_IID( __uuidof( IPersist ), IPersist, IPersistFile )

into the COM map of my class and it will work allright.

Is there any difference between the two?

+1  A: 

According to ATL Internals (a book you should definitely get, based on your questions here -- most of them are covered thoroughly!), the two are mostly equivalent.

  • COM_INTERFACE_ENTRY only mentions the interface name, and maps its IID to a vtable offset
  • COM_INTERFACE_ENTRY2 mentions the interface name and which branch in the inheritance tree to use for vtable offsetting
  • COM_INTERFACE_ENTRY_IID maps IID to interface, and thereby allows you to choose inheritance tree branch
  • COM_INTERFACE_ENTRY2_IID does it all; maps IID to interface, and is explicit about inheritance tree branch

The author of ATL Internals says:

Since COM_INTERFACE_ENTRY2[_IID] provides no extra functionality beyond that provided by COM_INTERFACE_ENTRY[_IID], I tend to always use the latter and forget the former.

I think they meant to say that if you use COM_INTERFACE_ENTRY_IID, you already choose the branch, so the COM_INTERFACE_ENTRY2[_IID] family doesn't add anything. But COM_INTERFACE_ENTRY2 is somewhat simpler to use that COM_INTERFACE_ENTRY_IID.

Kim Gräsman