Поделиться через


Указатели интерфейса и интерфейсы

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

Говоря именно об этом множественном косвенном использовании, это неудобно, поэтому вместо этого указатель на таблицу функций интерфейса, которую другой объект должен вызывать его методы, называется просто указателем интерфейса. Таблицы функций можно создавать вручную в приложении C или почти автоматически с помощью Visual C++ (или других объектно-ориентированных языков, поддерживающих COM).

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

Каждый интерфейс — это неизменяемый контракт функциональной группы методов. Вы ссылаетесь на интерфейс во время выполнения с глобальным уникальным идентификатором интерфейса (IID). Этот идентификатор IID, который является конкретным экземпляром глобально уникального идентификатора (GUID), поддерживаемого COM, позволяет клиенту задавать объект точно, поддерживает ли он семантику интерфейса, без лишних накладных расходов и без путаницы, которая может возникнуть в системе от нескольких версий одного и того же интерфейса с одинаковым именем.

Чтобы свести к сводные данные, важно понять, что такое COM-интерфейс, и это не так:

  • Com-интерфейс не совпадает с классом C++. Чистое виртуальное определение не несет реализации. Если вы являетесь программистом C++, вы можете определить реализацию интерфейса как класс, но это относится к заголовку сведений о реализации, которые COM не указывает. Экземпляр объекта, реализующего интерфейс, должен быть создан для фактического существования интерфейса. Кроме того, различные классы объектов могут реализовать интерфейс по-разному, но использовать взаимозаменяемо в двоичной форме, если поведение соответствует определению интерфейса.
  • COM-интерфейс не является объектом. Это просто связанная группа функций и является двоичным стандартом, с помощью которого клиенты и объекты взаимодействуют. Если он может предоставлять указатели на методы интерфейса, объект может быть реализован на любом языке с любым внутренним представлением состояния.
  • Интерфейсы COM строго типизированы. Каждый интерфейс имеет собственный идентификатор интерфейса (GUID), который устраняет возможность дублирования, которое может произойти с любой другой схемой именования.
  • Интерфейсы COM неизменяемы. Нельзя определить новую версию старого интерфейса и предоставить ей тот же идентификатор. Добавление или удаление методов интерфейса или изменение семантики создает новый интерфейс, а не новую версию старого интерфейса. Поэтому новый интерфейс не может конфликтуть со старым интерфейсом. Однако объекты могут одновременно поддерживать несколько интерфейсов и предоставлять интерфейсы, которые являются последовательными редакциями интерфейса с различными идентификаторами. Таким образом, каждый интерфейс является отдельным контрактом, и системные объекты не должны быть обеспокоены тем, является ли версия вызываемого интерфейса тем, который они ожидают. Идентификатор интерфейса (IID) определяет контракт интерфейса явно и уникально.

COM-объекты и интерфейсы