WinRT反射(C++/CX)

4

如何在C++/CX中反射一个对象?我知道可以使用IInspectable获取其类名,但我不知道如何获取其属性列表或者只有方法名(字符串)时如何调用方法。我在这里和谷歌上搜索了答案,但找到的都是关于WinRT的.NET层的内容(System.Reflection命名空间似乎在C++/CX中不可用)。


6
System命名空间下的内容将无法从C++/CX中使用,这些都是特定于.NET的。 - svick
3个回答

6
如svick所示,您需要取得类名(从IInspectable::GetRuntimeClassName中检索),将其传递给RoGetMetaDataFile。这将返回一个IMetaDataImport2。现在调用IMetaDataImport2::FindTypeDefByName。这将返回一个typedef token。现在调用IMetaDataImport2::GetTypeDefProps,它将为您提供有关类型的属性。
从typedef属性中,您可以检索其他信息 - 枚举方法/字段(如果它是接口/结构体(或枚举)),查找运行时类的类型(如果它是接口或类),等等。

在我在这里发布问题之前,我曾尝试使用RoGetMetaDataFile,但它不起作用(无法找到由GetRuntimeClassName返回的类型)。 - Atamiri
2
GetRuntimeClassName返回的字符串是什么?返回了什么错误?您传递给RoGetMetaDataFile的参数是什么? - Larry Osterman
1
可以不使用FindTypeDefByName,而是直接使用通过其最后一个输出参数返回的RoGetMetaDataFilemdTypeDef吗? - James McNellis

1

1

即使在WinRT应用程序中,大部分常规的.Net反射功能都不包含在可用的.Net子集中。我在WinRT文档中也没有找到任何与反射相关的类型。这意味着(除非我漏看了什么),可用的API并没有提供反射功能。

虽然我不明白为什么它不能使用。元数据是存在的,这应该足够了。

当查看特定于C++的函数时,有一个名为RoGetMetaDataFile()的函数。它似乎可以用来获取元数据。但这是一个本地C++函数,而不是C++/CX。这意味着使用它并不容易(需要手动内存管理等),而且我怀疑它是否允许在商店中的应用程序中使用。


相当确定应该使用RoGetMetaDataFile()来获取IMetaDataImport2接口指针。它是本机函数并不是问题,因为C++ / CX会生成本机代码。 - Hans Passant
1
没有理由不允许应用商店中的应用程序使用对象内省。苹果公司允许使用它。 - Atamiri
关于 RoGetMetaDataFile,我能够将其与外部组件的类一起使用(我在另一个项目中创建了一个 DLL),但不能与调用 RoGetMetaDataFile 的同一项目中的类一起使用。我认为这不是预期行为,显然我要么错误地使用了 RoGetMetaDataFile,要么这是早期预览版中的一个 bug。 - Atamiri
@Atamiri,我不知道原因。但我认为 .Net 反射在 .Net 的 WinRT 子集中几乎不存在这一事实说明了什么。 - svick
4
@svick,.NET反射在Metro样式应用程序中是可用的。诀窍在于使用System.Reflection命名空间下的GetTypeInfo()扩展方法。它在Type对象上被调用并返回一个包含缺失反射API的TypeInfo对象。 - John Lam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接