Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does implementing multiple COM interfaces work in C++?

I am trying to understand this example code regarding Browser Helper Objects.

Inside, the author implements a single class which exposes multiple interfaces (IObjectWithSite, IDispatch).

His QueryInterface function performs the following:

if(riid == IID_IUnknown) *ppv = static_cast<BHO*>(this);
else if(riid == IID_IObjectWithSite) *ppv = static_cast<IObjectWithSite*>(this);
else if (riid == IID_IDispatch) *ppv = static_cast<IDispatch*>(this);

I have learned that from a C perspective, interface pointers are just pointers to VTables. So I take it to mean that C++ is capable of returning the VTable of any implemented interface using static_cast.

Does this mean that a class constructed in this way has a bunch of VTables in memory (IObjectWithSite, IDispatch, etc)? What does C++ do with the name collisions on the different interfaces (they each have a QueryInterface, AddRef and Release function), can I implement different methods for each of these?

like image 828
Martin Avatar asked Jun 13 '10 23:06

Martin


1 Answers

Yes, there are multiple v-tables, one for each inherited interface. The static_cast<> returns it. The compiler makes sure that common methods in the inherited interfaces are shared, it fills each v-table slot with the a pointer to the same function. So you only need one implementation of AddRef, Release, QueryInterface. Just what you want. None of this is an accident.

This is only ever a problem when a coclass implements multiple interfaces with the same method that you don't want to give the same implementation. The IConnectionPoint::Advise() method is a notorious example. Or was it DAdvise()? Unfortunately, I don't remember what it clashed with and how it was solved, it was covered by ATL Internals. Very good book btw.

like image 106
Hans Passant Avatar answered Oct 27 '22 13:10

Hans Passant