如何使用midlrt.exe将.idl编译为.winmd?

时间:2019-06-30 09:31:18

标签: windows-runtime c++-winrt midl winrt-component

背景:我需要构建Windows运行时组件作为系统的一部分,该系统已设置为使用CMake生成其构建系统。作为准备步骤,我正在尝试在命令行上构建它。


从基本的idl文件(MyType.idl)开始

namespace NS
{
    [default_interface]
    runtimeclass MyType
    {
    }
}

我正在尝试使用midlrt.exe工具生成匹配的.winmd文件。以下命令行(为了便于阅读,将其分成几行)

midlrt
    /metadata_dir "%WindowsSdkDir%References\%WindowsSDKVersion%Windows.Foundation.FoundationContract\3.0.0.0"
    /reference "%WindowsSdkDir%References\%WindowsSDKVersion%Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd"
    /winmd MyType.winmd
    /notlb
    /winrt
    /nomidl
    /nologo
    /enum_class
    /ns_prefix
    /client none
    /server none
    MyType.idl

可以很好地生成MyType.winmd文件,但是我不知道为什么。我对/metadata_dir/reference选项感到特别困惑。运行midlrt /help提供以下功能:

/metadata_dir      Specify one or more directories containing platform metadata files
/reference         Specify one or more WinMD files to import

/metadata_dir上的官方文档没有太多添加(除了一个令人困惑的说法:“使用此开关来指定Windows主元数据文件的位置,该文​​件名为Windows。 winmd。” )。没有/reference的文档。

以下是我需要帮助的地方:

  • 我需要真正通过/metadata_dir选项吗?如上面的命令行中所使用,它看起来像是/reference选项一部分的冗余复制。不过,忽略它会产生编译器错误。
  • 如何确定所需的/reference列表,包括它们的特定版本?

1 个答案:

答案 0 :(得分:1)

需要

/ metadata_dir告诉MIDLRT它可以在哪里找到MIDLRT由于历史原因而需要的基础类型的定义。实际上,该目录必须指向包含winmd的目录,该目录定义了Windows SDK中Windows.Foundation命名空间的类型,但是如果遇到困难,则可以使用C:\ Windows \ System32 \ WinMetadata(因为前者很难实现)追查)。显然,您将只想进行测试/实验,因为您会碰巧正在运行的任何操作系统版本。正确的格式如下所示:

midlrt sample.idl /metadata_dir "C:\Program Files (x86)\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.FoundationContract\3.0.0.0"

寻找这条路很棘手。首先在注册表中找到SDK安装路径。然后选择您要定位的SDK版本。然后找到基础合同的最新版本。您可以在这里查看C ++ / WinRT如何做到这一点:

https://github.com/microsoft/xlang/blob/master/src/library/impl/cmd_reader_windows.h

/ reference是一个较新的功能,您可以使用它从winmd导入定义,而不必使用IDL导入/包括定义。这主要是一种优化,因为它比包含相应的IDL定义要快得多。

无论是否使用/ reference,您仍然都需要使用/ metadata_dir,因为它们用于不同的事物。这与cppwinrt.exe不同,在cppwinrt.exe中,它只有一个统一的-reference标志。