#.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()
вызову.