3

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

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

4

1 回答 1

3

cppwinrt.exe 编译器于 2017 年 11 月开始在Windows Preview SDK中发布。有了它,您可以更轻松地创建自己的 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 并验证它是否包含你所有的东西。

第 3 步:

运行 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不言自明。

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

于 2018-01-18T01:21:10.870 回答