次の方法で共有


C++/WinRT アプリから使用する C# Windows ランタイム コンポーネントの作成

このトピックでは、C++/WinRT プロジェクトに単純な C# コンポーネントを追加するプロセスについて説明します。

Visual Studio を使用すると、C# または Visual Basic で記述された Windows ランタイム コンポーネント (WRC) プロジェクト内で独自のカスタム Windows ランタイム型を作成して展開し、その WRC を C++ アプリケーション プロジェクトから参照し、そのアプリケーションからそれらのカスタム型を使用することが簡単になります。

内部的には、Windows ランタイム型は、UWP アプリケーションで許可されている任意の .NET 機能を使用できます。

外部的には、あなたの型のメンバーは、パラメーターおよび戻り値に対して Windows ランタイム型のみを公開できます。 ソリューションをビルドすると、Visual Studio によって .NET WRC プロジェクトがビルドされ、Windows メタデータ (.winmd) ファイルを作成するビルド ステップが実行されます。 これは、Visual Studio がアプリに含める Windows ランタイム コンポーネント (WRC) です。

.NET では、プリミティブ データ型やコレクション型など、一般的に使用される一部の .NET 型が、Windows ランタイムの同等の型に自動的にマップされます。 これらの .NET 型は、Windows ランタイム コンポーネントのパブリック インターフェイスで使用でき、対応する Windows ランタイム型としてコンポーネントのユーザーに表示されます。 C# および Visual Basicを使用した Windows ランタイム コンポーネントの を参照してください。

[前提条件]

空のアプリを作成する

Visual Studio で、空のアプリ (C++/WinRT) プロジェクト テンプレートを使用して新しいプロジェクトを作成します。 (ユニバーサル Windows) ではなく、(C++/WinRT) テンプレートを使用していることを確認します。

フォルダー構造がチュートリアルと一致するように、新しいプロジェクトの名前を CppToCSharpWinRT に設定します。

C# Windows ランタイム コンポーネントをソリューションに追加する

Visual Studio でコンポーネント プロジェクトを作成します。ソリューション エクスプローラーで、CppToCSharpWinRT ソリューションのショートカット メニューを開き、[の追加] 選択し、[新しいプロジェクト] 選択して新しい C# プロジェクトをソリューションに追加します。 [新しいプロジェクト の追加] ダイアログ ボックスの [インストール済みテンプレート] セクションで、[Visual C#] を選択し、[Windows] を選択し、[ユニバーサル] を します。 Windows ランタイム コンポーネント (ユニバーサル Windows) テンプレートを選択し、プロジェクト名 SampleComponent を入力します。

新しいユニバーサル Windows プラットフォーム プロジェクト ダイアログ ボックス で、最小バージョンとして [Windows 10 Creators Update (10.0; ビルド 15063) ] を選択します。 詳細については、以下の「アプリケーションの最小バージョン」セクションを参照してください。

C# GetMyString メソッドを追加する

SampleComponent プロジェクトで、クラスの名前を Class1 から Exampleに変更します。 次に、クラスに 2 つの単純なメンバー、プライベート フィールド、および GetMyStringという名前 インスタンス メソッドを追加します。

    public sealed class Example
    {
        int MyNumber;

        public string GetMyString()
        {
            return $"This is call #: {++MyNumber}";
        }
    }

既定では、クラスはパブリック シールとマークされます。 コンポーネントから公開するすべての Windows ランタイム クラスは、シールドする必要があります。

省略可能: 新しく追加されたメンバーに対して IntelliSense を有効にするには、ソリューション エクスプローラーで、SampleComponent プロジェクトのショートカット メニューを開き、[ビルド選択します。

CppToCSharpWinRT プロジェクトから C# SampleComponent を参照する

ソリューション エクスプローラーの C++/WinRT プロジェクトで、参照のショートカット メニューを開き、[参照の追加] 選択して、[参照 追加] ダイアログを開きます。 [プロジェクト ] を選択し、[ソリューション ] を選択します。 SampleComponent プロジェクトのチェック ボックスをオンにし、[OK] 選択して参照を追加します。

省略可能: C++/WinRT プロジェクトの IntelliSense を有効にするには、ソリューション エクスプローラーで、CppToCSharpWinRT プロジェクトのショートカットメニューを開き、ビルドを選択します。

MainPage.h の編集

MainPage.h プロジェクトで を開き、2 つの項目を追加します。 最初に、#include "winrt/SampleComponent.h" ステートメントの末尾に #include を追加してから、winrt::SampleComponent::Example 構造体に MainPage フィールドを追加します。

// MainPage.h
...
#include "winrt/SampleComponent.h"

namespace winrt::CppToCSharpWinRT::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
...
        winrt::SampleComponent::Example myExample;
...
    };
}

Visual Studio では、MainPage.h が [MainPage.xaml] の下に表示されます。

MainPage.cppの編集

MainPage.cppで、C# メソッド Mainpage::ClickHandlerを呼び出すように GetMyString の実装を変更します。

void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
    //myButton().Content(box_value(L"Clicked"));

    hstring myString = myExample.GetMyString();

    myButton().Content(box_value(myString));
}

プロジェクトを実行する

プロジェクトをビルドして実行できるようになりました。 ボタンをクリックするたびに、ボタン内の番号がインクリメントされます。

C# コンポーネントへの C++/WinRT Windows 呼び出しの スクリーンショット

ヒント

Visual Studio でコンポーネント プロジェクトを作成します。ソリューション エクスプローラーで、CppToCSharpWinRT プロジェクトのショートカットメニューを開き、[プロパティ] を選択し、[構成プロパティ] で[デバッグ] を選択します。 C# (マネージド) コードと C++ (ネイティブ) コードの両方をデバッグする場合は、デバッガーの種類を Managed と Native の に設定します。 C++ デバッグプロパティ

アプリケーションの最小バージョン

C# プロジェクト バージョンの アプリケーション最小 は、アプリケーションのコンパイルに使用される .NET のバージョンを制御します。 たとえば、Windows 10 Fall Creators Update (10.0;ビルド 16299) 以降では、.NET Standard 2.0 および Windows Arm64 プロセッサのサポートが有効になります。

ヒント

.NET Standard 2.0 または Arm64 のサポートが不要な場合は、追加のビルド構成を回避するために、16299 より前のバージョンの アプリケーション最小 を使用することをお勧めします。

Windows 10 Fall Creators Update (10.0;ビルド 16299) を設定する

C++/WinRT プロジェクトから参照される C# プロジェクトで .NET Standard 2.0 または Windows Arm64 のサポートを有効にするには、次の手順に従います。

Visual Studio でソリューション エクスプローラーに移動し、CppToCSharpWinRT プロジェクトのショートカット メニューを開きます。 [プロパティ] を選択し、ユニバーサル Windows アプリ最小バージョンを Windows 10 Fall Creators Update (10.0; に設定します。ビルド 16299) (またはそれ以降)。 SampleComponent プロジェクトでも同じ操作を行います。

Visual Studio で、CppToCSharpWinRT プロジェクトのショートカット メニューを開き、[プロジェクトのアンロード] 選択して、テキスト エディターで を開きます。

次の XML をコピーして、PropertyGroupの最初の CPPWinRTCSharpV2.vcxproj に貼り付けます。

   <!-- Start Custom .NET Native properties -->
   <DotNetNativeVersion>2.2.12-rel-31116-00</DotNetNativeVersion>
   <DotNetNativeSharedLibrary>2.2.8-rel-31116-00</DotNetNativeSharedLibrary>
   <UWPCoreRuntimeSdkVersion>2.2.14</UWPCoreRuntimeSdkVersion>
   <!--<NugetPath>$(USERPROFILE)\.nuget\packages</NugetPath>-->
   <NugetPath>$(ProgramFiles)\Microsoft SDKs\UWPNuGetPackages</NugetPath>
   <!-- End Custom .NET Native properties -->

DotNetNativeVersionDotNetNativeSharedLibrary、および UWPCoreRuntimeSdkVersion の値は、Visual Studio のバージョンによって異なる場合があります。 適切な値に設定するには、%ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages を開き、下の表の各値のサブディレクトリを確認します。 %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler ディレクトリには、2.2で始まるインストール済みのバージョンの .NET ネイティブを含むサブディレクトリがあります。 次の例では、2.2.12-rel-31116-00です。

MSBuild 変数 ディレクトリ
DotNetNativeVersion %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler 2.2.12-rel-31116-00
DotNetNativeSharedLibrary %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-x64.microsoft.net.native.sharedlibrary 2.2.8-rel-31116-00
UWPCoreRuntimeSdkVersion %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.UWPCoreRuntimeSdk 2.2.14

Microsoft.Net.Native.SharedLibrary でサポートされているアーキテクチャは複数あります。 x64 を適切なアーキテクチャに置き換えます。 たとえば、arm64 アーキテクチャは %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-arm64.microsoft.net.native.sharedlibrary ディレクトリにあります。

次に、最初の PropertyGroupの直後に、次のコードを追加します (変更なし)。

  <!-- Start Custom .NET Native targets -->
  <!-- Import all of the .NET Native / CoreCLR props at the beginning of the project -->
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\Microsoft.Net.UWPCoreRuntimeSdk.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-x86.Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-x64.Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-arm.Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm64.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-arm64.Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-x86.Microsoft.Net.Native.SharedLibrary.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-x64.Microsoft.Net.Native.SharedLibrary.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-arm.Microsoft.Net.Native.SharedLibrary.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm64.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-arm64.Microsoft.Net.Native.SharedLibrary.props" />
  <!-- End Custom .NET Native targets -->

プロジェクト ファイルの末尾で、終了 Project タグの直前に、次のコードを追加します (変更なし)。

  <!-- Import all of the .NET Native / CoreCLR targets at the end of the project -->
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-x86.Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-x64.Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-arm.Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm64.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-arm64.Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-x86.Microsoft.Net.Native.SharedLibrary.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-x64.Microsoft.Net.Native.SharedLibrary.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-arm.Microsoft.Net.Native.SharedLibrary.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm64.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-arm64.Microsoft.Net.Native.SharedLibrary.targets" />
  <!-- End Custom .NET Native targets -->

Visual Studio でプロジェクト ファイルを再読み込みします。 これを行うには、Visual Studio ソリューション エクスプローラーで、CppToCSharpWinRT プロジェクトのショートカット メニューを開き、[プロジェクト再読み込み] を選択します。

.NET Native 用のビルド

.NET ネイティブに対してビルドされた C# コンポーネントを使用して、アプリケーションをビルドしてテストすることをお勧めします。 Visual Studio で、CppToCSharpWinRT プロジェクトのショートカット メニューを開き、[プロジェクトのアンロード] 選択して、テキスト エディターで を開きます。

次に、UseDotNetNativeToolchain プロパティを、C++ プロジェクト ファイルの Release 構成と Arm64 構成で true するように設定します。

Visual Studio ソリューション エクスプローラーで、CppToCSharpWinRT プロジェクトのショートカット メニューを開き、[プロジェクト再読み込み] を選択します。

  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
...
    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Platform)'=='Arm64'" Label="Configuration">
    <UseDotNetNativeToolchain Condition="'$(UseDotNetNativeToolchain)'==''">true</UseDotNetNativeToolchain>
  </PropertyGroup>

他の C# nuget パッケージの参照

C# コンポーネントが他の nuget パッケージを参照している場合、アプリケーションのプロジェクト ファイルには、展開コンテンツとして nuget パッケージからのファイルの依存関係を一覧表示する必要があります。 たとえば、C# コンポーネントが Newtonsoft.Json nuget パッケージを参照している場合、同じ nuget パッケージとファイルの依存関係もアプリケーション プロジェクトで参照する必要があります。

SampleComponent.csproj ファイルに、nuget パッケージ参照を追加します。

    <PackageReference Include="Newtonsoft.Json">
      <Version>13.0.1</Version>
    </PackageReference>

CppToCSharpWinRT プロジェクトで、packages.config ファイルを見つけて、適切な nuget 参照を追加します。 これにより、nuget パッケージがソリューションのパッケージ フォルダーにインストールされます。

packages.configで、同じ nuget パッケージ参照を追加します。

  <package id="Newtonsoft.Json" version="13.0.1" targetFramework="native" developmentDependency="true" />

次に、次をアプリケーション プロジェクト ファイルに追加して、ソリューションのパッケージ フォルダーから適切なファイル依存関係を参照します。 たとえば、CppToCSharpWinRT.vcxproj で次を追加します。

  <ItemGroup>
    <None Include="..\packages\Newtonsoft.Json.13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll">
      <Link>%(Filename)%(Extension)</Link>
      <DeploymentContent>true</DeploymentContent>
    </None>
  </ItemGroup>
  • C# および Visual Basic を使用した Windows ランタイム コンポーネント
  • C++/WinRT を使用して Windows ランタイム コンポーネントを作成する