我正在使用COM-API,Autodesk Inventor。
此测试通过:
[Test]
public void CastTest()
{
Inventor.Document document = _application.ActiveDocument;
var assemblyDocument = (Inventor.AssemblyDocument)document;
Assert.NotNull(assemblyDocument);
}
此测试失败:
[Test]
public void IsAssignableFromTest()
{
Assert.IsTrue(typeof(Inventor.Document).IsAssignableFrom(typeof(Inventor.AssemblyDocument)));
}
我对COM一点都不太了解,有没有办法检查一个COM类型是否“继承”另一个使用反射或一些COM巫毒?
答案 0 :(得分:3)
COM类型系统与.NET不兼容。相反,你正在编写包装器(所谓的RCW)。为了测试是否可以将一个COM对象转换为另一个COM对象,COM将QueryInterface
- 方法作为IUnknown
的成员提供,每个COM对象都必须实现该方法。但是,.NET会为您隐藏这些详细信息,以便您可以编写“感觉”像.NET代码的COM代码。
如果您查看Inventors互操作库的反汇编,您会发现Document
和AssemblyDocument
之间没有直接关系。两者都是仅实现其各自coclass的默认接口的接口,并且归属于CoClassAttribute
。但是在他们的继承树中,它们并不直接相关。它们可能都实现了相同的接口(我想类似IDocument
),但你也不能将WinForms按钮转换为图片框,即使它们都是Control
- 接口。
这就是反射和IsAssignableFrom
正在测试的内容:每个CLR类型提供的元数据。 COM在这里工作不同。如果可以从另一个接口调用COM对象,则每个COM对象都可以自行“决定”它。因此它实现了QueryInterface
。因此,在执行测试之前,您必须创建源类型的实例(COM不知道静态成员)。
传统演员会调用QueryInterface
,因此您的测试可能看起来像:
[Test]
public void IsAssignableFromTest()
{
Assert.IsNotNull(_application.ActiveDocument as Inventor.AssemblyDocument);
}
否则,您可以通过Marshal
- 类直接致电QueryInterface
。
但是,无法通过COM对象反射来测试类型元数据。