Как делает реализацию нескольких работы COM-интерфейсов в C++?

Я пытаюсь понять этот пример кода относительно Объектов Помощника Браузера.

Внутри, автор реализует единый класс, который выставляет несколько интерфейсов (IObjectWithSite, IDispatch).

Его функция QueryInterface выполняет следующее:

if(riid == IID_IUnknown) *ppv = static_cast(this);
else if(riid == IID_IObjectWithSite) *ppv = static_cast(this);
else if (riid == IID_IDispatch) *ppv = static_cast(this);

Я узнал, что с точки зрения C, указатели на интерфейс являются просто указателями на VTables. Таким образом, я беру его, чтобы означать, что C++ способен к возврату VTable любого реализованного интерфейса с помощью static_cast.

Это означает, что класс, созданный таким образом, имеет набор VTables в памяти (IObjectWithSite, IDispatch, и т.д.)? Что C++ делает с коллизиями имени в различных интерфейсах (у каждого из них есть QueryInterface, AddRef и функция Выпуска), я могу реализовать различные методы для каждого из них?

5
задан Martin 25 August 2010 в 23:26
поделиться

2 ответа

Да, существует несколько v-таблиц, по одной для каждого унаследованного интерфейса. Static_cast <> возвращает его. Компилятор обеспечивает совместное использование общих методов в унаследованных интерфейсах, он заполняет каждый слот v-таблицы указателем на ту же функцию. Таким образом, вам нужна только одна реализация AddRef, Release, QueryInterface. Как раз то, что ты хочешь. Все это не случайно.

Это проблема возникает только тогда, когда компонентный класс реализует несколько интерфейсов с помощью одного и того же метода, который вы не хотите предоставлять одной и той же реализации. Известным примером является метод IConnectionPoint :: Advise (). Или это был DAdvise ()? К сожалению, я не помню, с чем это столкнулось и как было решено, это было покрыто ATL Internals. Кстати, очень хорошая книга.

7
ответ дан 13 December 2019 в 22:02
поделиться

При множественном наследовании несколько VTable упорядочиваются в последовательности, как в следующем формате, если задан этот указатель (который указывает в первый байт, 01)

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

В C ++ для каждого прототипа функции в сценарии с несколькими интерфейсами создается только одна реализация. Однако для обычного сценария наследования суперкласс может иметь предопределенную реализацию, и дочерние элементы, которые переопределяют функцию, будут иметь свои таблицы VTable, указывающие на содержимое, отличное от содержимого родительского.

3
ответ дан 13 December 2019 в 22:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: