Reflection IMetaDataImport和WinRT runtimeclass接口
在Visual Studio 2012附带的MS IDL版本中,对WinRT的支持添加了以下构造:Reflection IMetaDataImport和WinRT runtimeclass接口,reflection,windows-runtime,idl,Reflection,Windows Runtime,Idl,在Visual Studio 2012附带的MS IDL版本中,对WinRT的支持添加了以下构造: [activatable(Windows.Networking.Sockets.IControlChannelTriggerFactory, 0x06020000)] [threading(mta)] [marshaling_behavior(agile)] [version(0x060200
[activatable(Windows.Networking.Sockets.IControlChannelTriggerFactory,
0x06020000)]
[threading(mta)]
[marshaling_behavior(agile)]
[version(0x06020000)]
runtimeclass ControlChannelTrigger
{
[default] interface Windows.Networking.Sockets.IControlChannelTrigger;
interface Windows.Foundation.IClosable;
}
我正在使用IMetaDataImport分析winmd文件中的所有类型。如何确定“runtimeclass”实现了哪些接口,以及默认接口是哪个接口
如何找出“运行时类”实现的接口
Windows元数据文件由关系数据库组成:它基本上是一组相互关联的表。您可以在的分区II中找到逻辑模式的规范
每个运行时类和接口都由元数据数据库的TypeDef表中的一行表示。“类型X实现接口I和J”关系由InterfaceImpl表中的行表示,该表将类型定义映射到它们实现的接口
事实证明,计算由类型实现的接口集是相当困难的,原因有很多。假设我们要计算由XAML控件实现的接口集。需要执行以下所有步骤:
按钮
的元数据文件。你可以打电话来按钮
类型的元数据标记。这实际上是该类型的唯一标识符。你可以打电话来按钮直接实现的所有接口。这可以通过打电话来完成
按钮
类型派生自该类型。这是由TypeDef表的extends字段指定的,您可以通过调用来获得该字段。我们需要计算它实现的所有接口。然后,我们需要在类层次结构中一直执行相同的操作——对于按钮
,有很多类型:内容控件
,控件
,框架元素
,UIElement
,和依赖对象
请注意,其中一些类型可能在另一个元数据文件中定义。在这种情况下,InterfaceImpl将通过TypeRef令牌而不是TypeDef令牌引用接口。TypeRef表包含对类型的引用。您需要解析该引用,加载正确的元数据文件,并在该元数据文件中找到目标类型。这可以使用我们已经为按钮执行的步骤来完成
按钮
类型直接关联的InterfaceImpl,可以找到默认接口:默认接口将应用该属性(请注意,自定义属性应用于InterfaceImpl,而不是接口类型)。可以使用枚举每个InterfaceImpl的自定义属性
所以,这是一个非常多的工作,它需要大量的代码。我发现imeadataimport
接口及其好友的处理方式非常不友好,因此我为Boost编写了自己的。CxxReflect元数据库提供了比IMetaDataImport更好的类型检查,并包含解析签名所需的逻辑。它的速度不如IMetaDataImport,但正在接近
CxxReflect反射库包含用于跨元数据文件边界解析类型以及与Windows运行时集成的大部分逻辑。它仍处于alpha质量阶段,但对于普通任务来说效果很好(它目前正在进行一些重构,以使类型解析逻辑可用于反射以外的用途)
您当然可以自己实现逻辑来完成这项工作,但这非常繁琐。在CxxReflect的开发过程中,我多次发现了另一个我没有考虑的问题,不得不进行大量的返工。规范是完整的,但并不总是很清楚应该如何工作。顺便说一句,带有DefaultAttribute的接口将是RuntimeClass用作API参数时使用的接口。谢谢:EnumInterfaceImpls实际上就是我想要的。在我的例子中,所有其他继承的情况都将很自然地消失,因为它将映射到多重继承(在Python中)。@Martinv.Löwis:您正在构建Python语言投影吗?@Martinv.Löwis:很好!听起来很有趣。:-)