Как .NET COM Callable Wrapper генерирует IID? - PullRequest
8 голосов
/ 03 июля 2011

Просмотр сгенерированного файла TLB, созданного CCW, хотя OLE / COM Object Viewer показывает, что IID остается неизменным, пока я не изменю дизайн интерфейса (что является правильным поведением), меня беспокоит то, что если я скомпилирую этот же код на на другой машине будет сгенерирован совершенно другой IID, несмотря на то, что интерфейс не меняется и, следовательно, ломает существующие COM-клиенты.

  1. Как идентификаторы COM-интерфейса генерируются с помощью COM Callable Wrapper?
  2. Как CCW узнает, изменился ли интерфейс и нужно ли создать новый IID?
  3. Было бы безопаснее просто сгенерировать свою собственную и объявить в исходном файле?

1 Ответ

5 голосов
/ 03 июля 2011

Guid для типа не относится к COM-взаимодействию, все типы .NET имеют guid.Вы можете получить его из свойства Type.GUID.Код в CLR, который его генерирует, доступен из дистрибутива SSCLI20.Вы можете посмотреть на алгоритм, проверив код в clr / scr / vm / methodtable.cpp, MethodTable :: GetGuid () method.

Обобщение алгоритма:

  • , если тип имеет атрибут [Guid], затем вернуть это
  • , если тип является типом интерфейса, а затем сгенерировать строковую версию определения типа интерфейса.Это делается с помощью GetStringizedItfDef () в interoputil.cpp.Он начинается с полного имени типа и добавляет строковую версию каждого определения члена.
  • для всех других типов, генерирует строковую версию класса.Он начинается с полного имени типа, добавляет имя класса и добавляет полное имя сборки.
  • результирующая строка затем хэшируется в Guid с помощью вспомогательной функции CorGuidFromNameW ().

Этого достаточно, чтобы ответить на ваши вопросы:

Как идентификаторы COM-интерфейса генерируются COM Callable Wrapper?

Используется Type.GUID в том виде, как он генерируется.с алгоритмом выше.Ни один из элементов в алгоритме не является специфическим для машины, на которой он выполняется, поэтому вам не нужно бояться получать разные IID и CLSID на разных машинах сборки.

Как CCW узнает, еслиИнтерфейс изменился и должен генерировать новый IID?

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

Было бы безопаснее просто сгенерировать свой собственный и объявить в исходном файле?

Не совсем,Для этого алгоритма нет документированного режима отказа.Использование собственного атрибута [Guid] значительно увеличивает вероятность того, что вы забудете изменить его, когда это будет необходимо.Это ярлык, который часто используется и основной источник DLL Hell.Мерзкий тип, который приводит к сбою клиента с почти невозможной диагностикой аппаратных исключений.В отличие от все еще сложного, но не невозможного вида E_NOINTERFACE.На самом деле я могу думать только о двух недостатках, полагаясь на автоматически сгенерированный Guid: он имеет тенденцию вызывать загрязнение реестра на вашем компьютере разработчика, если вы забыли отменить сборку сборок перед их сборкой.И это немного замедляет работу при устранении неполадок, связанных с ошибками COM, потому что вы не знаете руководства.Правда, загрязнение реестра - это достаточно веская причина для меня.

...