为什么C++/WinRT需要XAML的IDL文件?

hm2xizp9  于 2023-04-03  发布在  其他
关注(0)|答案(2)|浏览(181)

对于C#,XAML转换为.cs*.g.cs)文件,不需要IDL文件。
同样在C++中,为什么XAML不能转译为.cpp*.g.cpp)文件?为什么它需要任何IDL文件?
我不明白。

ylamdve6

ylamdve61#

关于各个部分如何组合在一起的问题中存在相当多的混淆。转换的主要驱动程序是IDL文件。无论它是由开发人员编写的还是由IDE合成的,都是IDL生成WINMD(Windows元数据)文件,这些文件以与语言无关的方式描述接口和运行时类。
WINMD被所有需要查找类型、查询成员(如属性、事件、委托)和生成应用程序包的工具使用。
另一方面,XAML根本不是编译过程的一部分。虽然它的一些内容在编译时进行了验证,但它通常会被转换为一个紧凑的二进制表示(XBF),在运行时加载和解析以示例化类型。
关于为什么C++/WinRT需要IDL(而不是C#或C++/CX)的问题很容易回答:从C类定义中派生出足够的信息来明确地推导出所需的元数据是不可能的。
举一个简单的例子,考虑属性。虽然C#C++/CX都有专门的语言结构来描述属性,但C
不是这种情况。C++/WinRT将属性投影到带零个或一个参数的成员函数(分别用于getter和setter)。如果要从C类定义自动推导元数据,还有其他的挑战,虽然Kenny Kerr一再表示希望为C/WinRT获得更好的IDE支持,但Visual Studio团队似乎并不太关心(例如,请参阅此评论)。
在可预见的将来,如果您选择使用C++/WinRT,则应该准备编写IDL文件。

js5cn81o

js5cn81o2#

我很喜欢这个问题,我也喜欢IInspectable's answer。不过,我想用不同的方法来回答这个问题。

时间;日期

简而言之:
您必须为C++/WinRT编写IDL,因为C++/WinRT不会(不能)从您的代码自动生成WinMD,XAML编译器使用它来了解哪些控件和类型可用。

C#和C++/CX会自动从您的代码中生成相应的WinMD,因此您无需创建IDL

为什么XAML转不成.g.cpp文件?

对于C#,XAML转换为.cs*.g.cs)文件,不需要IDL文件。
同样在C++中,为什么不能将XAML转译为.cpp*.g.cpp)文件?

**XAML * 确实 * 为您创建代码文件!**无论您使用哪种语言,C#或C++(包括C++/WinRT和C++/CX),XAML编译器 * 确实 * 为您生成文件-例如,在我目前的C++/WinRT工作中,我看到MyControl.g.hMyControl.g.cppMyControl.xaml.g.hMyControl.xaml.g.hpp

部分是C++/WinRT,部分是XAML编译器。这些代码会以复杂的方式自动包含在您的项目中(如果您好奇,请阅读XamlTypeInfo---Visual Studio团队有an old blog post)。

为什么在C++/WinRT中XAML需要IDL文件?

为什么它需要IDL文件呢?
但这是关键点---这些生成的代码文件不是XAML编译器所需要的,无论是哪种语言。
XAML编译器需要.winmd s
WinMD files基本上是WinRT代码(Windows API使用的代码类型)的“类型描述”。您可以actually look through them with tools like ildasm。XAML将这些类型用于x:Bind等内容---以及简单地了解控件。

示例

例如,使用以下代码:

<!-- MyPage.xaml -->
<MyControl
    Title="{x:Bind MyViewModel.CoolTitle, Mode=OneWay}" />

XAML如何知道MyControl?它如何知道MyViewModel,或者MyViewModel具有CoolTitle属性?

在C#和C++/CX中,语言的编译器(例如C#编译器或C++/CX编译器)读取您的类型并自动生成WinMD。在C#的情况下,这就是.NET的工作方式---每个类最终都会在WinMD的某个地方结束/可以通过WinMD进行描述。在C++/CX的情况下,that's what the "CX" part was--- C++ 的一个扩展,它允许你在代码中创建WinRT类型。帽子指针(^ref new)等等。

但是,在C++/WinRT中,我们不会自动生成WinMD。
C++/WinRT比C++/CX提供了很多好处,但一个关键的区别是它没有特殊的编译器--所以它不能读取你的代码并生成WinMD文件。* 相反 *,你必须自己编写IDL。
希望能有所帮助!

相关问题