Почему указатели IUnknown *, полученные через разные интерфейсы одного и того же COM-объекта, имеют одинаковое значение? - PullRequest
3 голосов
/ 22 апреля 2011

У меня есть следующая иерархия COM-интерфейсов и класс, реализующий их:

interface IX : public IUnknown{};
interface IY : public IUnknown{};
class CA: public IX, public IY{};

Здесь class CA эффективно наследуется от IUnknown дважды.

Мы знаем, что в class CA есть два указателя vtable - один указывает на IX, а другой - на IY. Таким образом, IUnknown, хранящийся в подобъекте IX, отличается от IUnknown, хранящемся в подобъекте IY.

Тем не менее, когда мы вызываем IX::QueryInterface() или IY::QueryInterface() для того же объекта и запрашиваем IUnknown, мы получаем идентичные IUnknown* указатели.

Почему это происходит?

1 Ответ

7 голосов
/ 22 апреля 2011

Это так называемое требование "идентичности объекта" , в котором говорится, что всякий раз, когда вы запрашиваете IUnknown у двух объектов, вы получаете разные указатели, если это разные объекты, и равные указатели, если это один и тот же объект.

Каждая QueryInterface() реализация должна соответствовать этому требованию.Обычно это делается с помощью , который выбирает, какой IUnknown вернуть, и придерживается его :

HRESULT CA::QueryInterface( REFIID iid, void** ppv )
{
    if( iid == __uuidof( IUnknown ) ) {
        // Explicitly cast to one of base class subobjects.
        // Doesn't matter which one is chosen - it just has to be
        // the same base class subobject each time IUnknown is requested.
       IUnknown* selected = static_cast<IX*>( this );
       *ppv = selected;
       AddRef();
       return S_OK;
    } else {
       continue for other interfaces
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...