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


Когда следует использовать глобальную таблицу интерфейсов

Если вы размыкаете указатель интерфейса несколько раз между квартирами в процессе, можно использовать интерфейс IGlobalInterfaceTable. С другими методами вам придется повторно маршал каждый раз.

Примечание.

Если указатель интерфейса не используется только один раз, может потребоваться использовать функцию CoMarshalInterThreadInterfaceInStream. Кроме того, его можно использовать для передачи указателя интерфейса из одного потока в другой поток в том же процессе.

 

Интерфейс IGlobalInterfaceTable также делает еще одну ранее сложную проблему проще для программиста. Эта проблема возникает при применении следующих условий:

  • Инпроцессный гибкий объект объединяет маршалер с бесплатным потоком.
  • Этот же гибкий объект также содержит указатели интерфейса (как переменные-члены) на другие объекты, которые не являются гибкими и не агрегируют маршалер с бесплатным потоком.

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

Чтобы устранить эту проблему, внешний объект, агрегирующий маршалер с свободным потоком, должен вызывать IGlobalInterfaceTable::RegisterInterfaceInGlobal на внутреннем интерфейсе и хранить полученный файл cookie в своей переменной-члене вместо хранения фактического указателя интерфейса. Когда внешний объект хочет вызвать указатель интерфейса внутреннего объекта, он должен вызвать IGlobalInterfaceTable::GetInterfaceFromGlobal, использовать возвращаемый указатель интерфейса, а затем освободить его. Когда внешний объект исчезнет, он должен вызвать IGlobalInterfaceTable::RevokeInterfaceFromGlobal , чтобы удалить интерфейс из глобальной таблицы интерфейсов.

Создание глобальной таблицы интерфейса