IIn*_*ble 12 c++ windows-runtime c++-cx win-universal-app c++-winrt
本周早些时候,Kenny Kerr 在CppCon 2016 1上展示了C++/WinRT.它是基于Modern的Windows Runtime的标准C++投影.
据我所知,C++/CX编译器/预处理器/代码生成器不接触标准C++代码,而C++/WinRT是标准C++库,这是我天真的解释,C++/CX和C++/WinRT都可以在同一个项目中使用.
问题:
如果重要的话,那些问题的答案让我现在可以决定如何将我的C++/CX项目推向未来.
Ken*_*err 14
简而言之,是的,C++/CX和C++/WinRT可以在同一个项目中使用.
C++/CX编译器将Winmd类型注入根命名空间.C++/WinRT将所有内容包装在其自己的根winrt命名空间中,以适应与C++/CX的互操作,并避免与其他库的C++编译器模糊错误.所以下面的C++/CX代码:
using namespace Windows::Foundation;
using namespace Windows::Networking;
Uri ^ uri = ref new Uri(L"https://moderncpp.com/");
HostName ^ name = ref new HostName(L"moderncpp.com");
Run Code Online (Sandbox Code Playgroud)
可以用C++/WinRT重写如下:
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Networking;
Uri uri(L"https://moderncpp.com/");
HostName name(L"moderncpp.com");
Run Code Online (Sandbox Code Playgroud)
或者,如果您正在使用/ ZW进行编译,那么您可以按如下方式重写它(以避免错误C2872:'Windows':模糊符号):
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Networking;
Uri uri(L"https://moderncpp.com/");
HostName name(L"moderncpp.com");
Run Code Online (Sandbox Code Playgroud)
您可以将C++/CX和C++/WinRT组合在同一源文件中的另一种方法是使用根命名空间,如下所示:
namespace cx
{
using namespace Windows::Foundation;
using namespace Windows::Networking;
}
namespace winrt
{
using namespace Windows::Foundation;
using namespace Windows::Networking;
}
void Sample()
{
cx::Uri uri(L"https://moderncpp.com/");
winrt::HostName name(L"moderncpp.com");
}
Run Code Online (Sandbox Code Playgroud)
在一天结束时,C++/WinRT只是一个标准的C++库,您可以将其包含在任何适用的C++项目中.但是,C++/CX和C++/WinRT确实以非常不同的方式处理元数据.C++/CX直接消耗和生成元数据,而C++/WinRT受标准C++的约束,因此需要一个独立的工具(cppwinrt.exe)来帮助弥合这一差距.
关于“C++/WinRT 能否使用在同一项目中使用 C++/CX 实现的类型?”这一问题
答案是“是”和“否”。在同一项目中定义“引用类”时,由于此类项目必须在启用 C++/CX 的情况下进行编译,因此您的代码可以像使用任何引用类一样简单地使用该类。
但是,如果您想将“ref 类”用作 C++/WinRT 投影,答案实际上是否定的。
为了获取 C++/WinRT 投影类定义,需要对“引用类”的元数据运行 cppwinrt.exe 编译器。这需要以某种方式获取元数据。您可以设置某种机制来编译“引用类”一次,获取 winmd,通过 mdmerge 对其进行处理以将其置于规范形式,在元数据上运行 cppwinrt.exe 以获取预计的类定义,然后包含生成的标头。
或者,您可以编写 IDL 来描述“ref 类”,使用 MIDLRT 将其编译为元数据,然后运行 cppwinrt.exe。IMO 两者都不实用。
最合理的替代方案是简单地使用 ref 类作为 C++/CX 类型,因为定义位于同一解决方案中。下一个最实用的解决方案是将类放在一个单独的项目中,编译它并获取 winmd,然后从 winmd 创建标头。这种方法还允许在不使用 C++/CX 代码的情况下构建使用“引用类”(通过投影)的单独项目。
为了完全透明,请注意,我们的初始版本(现已在https://github.com/Microsoft/cppwinrt提供)不包含 cppwinrt.exe 编译器本身。相反,它包含 C++/WinRT 头文件,其中包含 Windows 10 周年更新 SDK 中定义的所有 Windows 运行时类型/API 的投影 - 这包括通用平台 API 和所有扩展 SDK API。