Кастинг интерфейса взаимодействия COM

#.net #com-interop #com-interface

#.net #com-взаимодействие #com-интерфейс

Вопрос:

Следуя этой статье, я успешно перевел объявление COM-класса / интерфейса C в C # следующим образом:

 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(IfaceGuid)]
public interface IFoo
{
  void Bar();
}

[ComImport, Guid(ClassGuid)]
public class Foo
{ }
  

Я использую его следующим образом:

 var foo = new Foo();
var ifoo = (IFoo)foo;

ifoo.Bar();
  

Мой вопрос в том, как это может работать, учитывая, что это Foo не реализуется IFoo (даже во время выполнения typeof(Foo).GetInterfaces() является пустым) и что пользовательские преобразования в интерфейсы запрещены?

Это какая-то специальная обработка, зарезервированная только для COM? Что об этом говорится в спецификации C #?

Ответ №1:

ComImport типы обрабатываются иначе, чем «обычные» .Классы NET, поскольку они представляют собой оболочку, вызываемую во время выполнения, вокруг базового сокласса COM. Приведение экземпляра одного из них к типу интерфейса COM прозрачно отображается в вызов объектной реализации метода интерфейса COM IUnknown.QueryInterface .

Если QI для запрошенного интерфейса выполняется успешно на уровне COM, то приведение C # также будет успешным.

Ответ №2:

Ну, да, приведение классов, помеченных как ComImport , к COM-интерфейсам приводит к QueryInterface() «под капотом» — я думаю, это делается внутри RCW.

Этот способ new приводит к CoCreateInstance() вызову, а затем приведение приводит к QueryInterface() вызову.