5

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?

Martin
  • 5,945
  • 7
  • 50
  • 77

2 Answers2

7

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    Thanks! I have done some reading of my own and I discovered that it not only creates different VTables, but also creates "thunk" functions to fixup the pointer before redirecting back to the common function. – Martin Jun 14 '10 at 11:43
3

In multiple inheritance, multiple VTables are arranged in sequence like following format if given this pointer (which point to first byte, 01)

[01][02][03][04] [05][06][07][08] [09][10][11][12]
[Ptr of VTableA][Ptr of VTableB][Ptr of VTableC]

In C++, only 1 implementation will be generated per function prototype in multiple interface scenario. However for normal inheritance scenario, superclass might have pre-defined implementation and children who overrides the function will have their VTables pointing to different content than the parent.

YeenFei
  • 3,180
  • 18
  • 26