【问题标题】:How to use midlrt.exe to compile .idl to .winmd?如何使用midlrt.exe 将.idl 编译为.winmd?
【发布时间】:2019-06-30 09:31:18
【问题描述】:

背景:我需要构建一个 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 选项的一部分的冗余复制。但是,将其排除在外会产生编译器错误。
  • 如何确定所需的 /references 列表,包括其特定版本?

【问题讨论】:

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


    【解决方案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 不同,它只有一个统一的 -reference 标志。

    【讨论】:

    • 所以/reference 在 IDL 中的作用与 C++ 代码中的 /FI (Name Forced Include File) 编译器开关相同,方法是扩展相应的文件,就好像它被包含/导入到代码中一样。这回答了这个问题。我仍然需要帮助来确定如何确定 /metadata_dir 参数。 C++/WinRT VSIX 似乎做得很好,但我很难弄清楚它如何将所需的位置收集到生成的响应文件中。有这方面的文件吗?
    • 我已经扩展了我的答案来描述这个。
    猜你喜欢
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 2017-06-21
    • 2021-06-01
    • 2011-10-25
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    相关资源
    最近更新 更多