【问题标题】:Consuming C++/WinRT Components from C#从 C# 使用 C++/WinRT 组件
【发布时间】:2017-11-17 01:35:30
【问题描述】:

我有一个用 C++/CX 编写的项目(动态库),该项目由一个用 C#(针对 x86 和 ARM32)编写的 Windows 10 通用应用程序使用。
我想将库重写为 C++/WinRT 以使用 vanilla C++。

Q1:是否可以创建 C++/WinRT DLL 并从 C# 中使用它?
Q2:如何设置 C++/WinRT 项目以使其能够从商店应用程序中使用?

【问题讨论】:

  • 这是可能的,尽管在当前版本中非常乏味。当前没有工具支持生成使用以 C++/WinRT 编写的 Windows 运行时组件所需的元数据。一旦 cppwinrt.exe 编译器向公众开放,用 C++/WinRT 编写 WinRT 组件将是可行的。
  • 嗨@IInspectable,此工具支持的提供日期是什么时候?谢谢!
  • 据我所知,还没有官方声明,何时发布。 GitHub 存储库中有一些 cmets(例如 hereherehere)已表达了发布 cppwinrt.exe 编译器的意图。
  • 感谢您的更新。我会紧紧抓住的。
  • 我读this comment的方式,听起来cppwinrt.exe编译器将在下一个版本中发布(从.winmd文件生成头文件是cppwinrt.exe编译器的工作之一)。目前还不清楚下一个版本何时发布,或者它是否会附带一个功能齐全的 cppwinrt.exe 编译器。不幸的是。

标签: c# windows-runtime c++-cx winrt-component c++-winrt


【解决方案1】:

cppwinrt.exe 编译器于 2017 年 11 月至 987654321@ 开始发布。有了它,您可以更轻松地创建自己的 C++/WinRT 组件,以便其他商店应用程序可以使用它。

在 github (https://github.com/kennykerr/cppwinrt/tree/master/Store/Component) 上有一个示例,用于 C++ 商店应用程序。显然,对于 C# 应用程序,App 项目需要有所不同,但这应该足以让您入门。特别是,C++/WinRT 组件项目虽然很基础,但包含创建组件所需的大部分魔法。

我们正在积极努力使这种体验与项目模板和其他好东西更加无缝,但目前,您仍然可以通过类似于链接示例的方式来实现这一点,而无需太多工作。

示例中发生的事情的简短版本是:

  1. 在 IDL 文件中定义组件的 API
  2. 调用 MIDL 将 IDL 编译为元数据 (.winmd)
  3. 调用 cppwinrt.exe 编译器生成脚手架,以实现您的运行时类以及激活所需的 DllGetActivationFactory 挂钩。

想要了解正在发生的事情的详细信息吗?

第 1 步:IDL

示例的 API 非常简单,所以我将在此处发布。

import "Windows.Foundation.idl";

namespace Component
{
  runtimeclass Button;

  [version(1.0), uuid(461c8806-8bc2-4622-8eac-b547c39f867e), exclusiveto(Button)]
  interface IButton : IInspectable
  {
    [propget] HRESULT Text([out,retval] HSTRING* value);
  };

  [version(2.0), uuid(d3235252-4081-4cc8-b0e0-8c7691813845), exclusiveto(Button)]
  interface IButton2 : IInspectable
  {
      HRESULT Show();
  };

  [version(1.0), activatable(1.0)]
  runtimeclass Button
  {
      [default] interface IButton;
      interface IButton2;
      interface Windows.Foundation.IStringable;
  }
}

第 2 步:创建 winmd

这只需要您将正确的命令行参数传递给 MIDL,可以在 Visual Studio 中看到项目属性和 IDL 文件的属性。你需要的是:

  • 启用 Windows 运行时(添加 /winrt)
  • 添加您的元数据参考目录。如果您的目标是 16299 SDK,这将是 $(FrameworkSdkDir)References\10.0.16299.0\Windows.Foundation.FoundationContract\3.0.0.0。如果您针对不同的 SDK,请适当更新。
  • 设置您的输出元数据文件。通常将其设置为$(ProjectName).winmd 是最简单的
  • 将 /nmidl 和 /struct_by_ref 添加到 MIDL 命令行。相信我。

此时,构建项目现在应该会生成一个 winmd 文件。在链接的示例中,它将被命名为 Component.winmd。如果你愿意,你可以使用 ildasm 来破解 winmd 并验证它是否包含你所有的东西。

第三步:

运行 cppwinrt.exe 以生成脚手架。您可以在 Component 项目中看到它有一个 CustomBuildStep,它使用一些参数调用 cppwinrt.exe:cppwinrt.exe -in $(ProjectDir)Component.winmd -comp $(ProjectDir) -out "$(ProjectDir)Generated Files" -ref 10.0.17061.0 -verbose

  • -in 输入的 winmd 位置。这是您在第 2 步中生成的内容。
  • -comp我们在“组件”模式下运行,所以它会生成脚手架。
  • -out 生成的脚手架放在哪里。
  • -ref 在哪里可以找到您的 winmd 所依赖的输入 winmd。您还可以指定一个 SDK 版本(这就是这里发生的事情)或 -ref local 以简单地使用您正在运行的操作系统上的任何内容。使用 SDK 版本是最干净的。
  • -verbose 不言自明。

下载示例项目并试一试。从那里开始,希望可以直接设置您自己的组件和应用程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 2013-02-20
    • 2013-12-24
    • 1970-01-01
    • 2020-08-21
    • 2012-09-15
    • 2020-12-17
    相关资源
    最近更新 更多