このトピックでは、C++/WinRT プロジェクトに単純な C# コンポーネントを追加するプロセスについて説明します。
Visual Studioを使用すると、C# または Visual Basic で記述された Windows ランタイム コンポーネント (WRC) プロジェクト内で独自のカスタム Windows ランタイム型を作成してデプロイし、その WRC を C++ アプリケーション プロジェクトから参照し、そのアプリケーションからそれらのカスタム型を使用することが簡単になります。
内部的には、Windows ランタイム型は、UWP アプリケーションで許可されている任意の.NET機能を使用できます。
Note
詳細については、C# と UWP アプリのVisual Basicと.NETを使用したWindows ランタイムコンポーネントの概要に関するページを参照してください。
外部からは、その型のメンバーは、パラメーター型と戻り値の型として Windows ランタイム 型のみを公開できます。 ソリューションをビルドするときに、Visual Studio.NET WRC プロジェクトをビルドし、Windows メタデータ (.winmd) ファイルを作成するビルド ステップを実行します。 これはWindows ランタイム コンポーネント (WRC) であり、Visual Studioアプリに含まれています。
Note
.NETでは、プリミティブ データ型やコレクション型など、一般的に使用される一部の.NET型が、Windows ランタイムに対応するものに自動的にマップされます。 これらの.NET型は、Windows ランタイム コンポーネントのパブリック インターフェイスで使用でき、対応するWindows ランタイム型としてコンポーネントのユーザーに表示されます。 C# とVisual Basic Windows ランタイムコンポーネントを参照してください。
前提条件
- ウィンドウズ10
- Microsoft Visual Studio
空のアプリを作成する
Visual Studioで、空のアプリ (C++/WinRT) プロジェクト テンプレートを使用して新しいプロジェクトを作成します (WinUI 3 デスクトップ アプリの場合は、空のアプリ、パッケージ (デスクトップの WinUI 3) テンプレートを使用します)。 (ユニバーサル Windows) テンプレートではなく、(C++/WinRT) テンプレートを使用していることを確認します。
フォルダー構造がチュートリアルと一致するように、新しいプロジェクトの名前を CppToCSharpWinRT に設定します。
C# Windows ランタイム コンポーネントをソリューションに追加する
Visual Studioで、コンポーネント projectを作成します。ソリューション エクスプローラーで、CppToCSharpWinRT ソリューションのショートカット メニューを開き、[追加] を選択し、[新しいProject] を選択して新しい C# projectをソリューションに追加します。 [新しいProjectの追加] ダイアログ ボックスの [インストールされているテンプレート] セクションで、[Visual C#] を選択し、[Windows]、[ユニバーサル] の順に選択します。 Windows ランタイム コンポーネント (ユニバーサル Windows) テンプレートを選択し、プロジェクト名として SampleComponent を入力します。
Note
[新しいユニバーサル Windows プラットフォーム プロジェクト] ダイアログ ボックスで、最小バージョンとして Windows 10 Creators Update (10.0; Build 15063) を選択します。 詳細については、以下の 「アプリケーションの最小バージョン 」セクションを参照してください。
C# GetMyString メソッドを追加する
SampleComponent プロジェクトで、クラスの名前を Class1 から Example に変更します。 次に、プライベート int フィールドと GetMyString という名前のインスタンス メソッドの 2 つの単純なメンバーをクラスに追加します。
public sealed class Example { int MyNumber; public string GetMyString() { return $"This is call #: {++MyNumber}"; } }
Note
既定では、クラスは パブリック シールとしてマークされます。 コンポーネントから公開するすべてのWindows ランタイム クラスをシールする必要があります。
Note
省略可能: 新しく追加されたメンバーに対して IntelliSense を有効にするには、ソリューション エクスプローラーで SampleComponent プロジェクトのショートカット メニューを開き、[ビルド] を選択します。
CppToCSharpWinRT プロジェクトから C# SampleComponent を参照する
ソリューション エクスプローラーの C++/WinRT プロジェクトで、[参照] のショートカット メニューを開き、[参照の追加] を選択して [参照の追加] ダイアログを開きます。 [ プロジェクト] を選択し、[ソリューション] を選択 します。 SampleComponent プロジェクトのチェック ボックスをオンにし、[OK] を選択して参照を追加します。
Note
省略可能: 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;
...
};
}
Note
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));
}
プロジェクトを実行する
プロジェクトをビルドして実行できるようになりました。 ボタンをクリックするたびに、ボタン内の番号がインクリメントされます。
Tip
Visual Studioで、コンポーネント プロジェクトを作成します。ソリューション エクスプローラーで、CppToCSharpWinRT プロジェクトのショートカット メニューを開き、[プロパティ] を選択し、[構成プロパティ] で [デバッグ] を選択します。 C# (マネージド) コードと C++ (ネイティブ) コードの両方をデバッグする場合は、デバッガーの種類をマネージドとネイティブに設定します。
アプリケーションの最小バージョン
C# プロジェクト バージョンの Application Minimum は、アプリケーションのコンパイルに使用される.NETのバージョンを制御します。 たとえば、Windows 10 Fall Creators Update (10.0;ビルド 16299) 以降では、.NET Standard 2.0 および Windows Arm64 プロセッサのサポートが有効になります。
Tip
.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 プロジェクトのショートカット メニューを開きます。 [プロパティ] を選択し、Universal Windows アプリ の最小バージョンを Windows 10 Fall Creators Update (10.0; ビルド 16299)(またはそれ以降のバージョン)に設定します。 SampleComponent プロジェクトに対して同じ操作を行います。
Visual Studioで、CppToCSharpWinRT projectのショートカット メニューを開き、[アンロード] Projectを選択してテキスト エディターでCppToCSharpWinRT.vcxprojを開きます。
次の 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 -->
DotNetNativeVersion、DotNetNativeSharedLibrary、および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.Compiler2.2.12-rel-31116-00DotNetNativeSharedLibrary %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-x64.microsoft.net.native.sharedlibrary2.2.8-rel-31116-00UWPCoreRuntimeSdkVersion %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.UWPCoreRuntimeSdk2.2.14
Note
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)' >= '10.0.16299.0'" Project="$(NugetPath)\Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\Microsoft.Net.UWPCoreRuntimeSdk.props" />
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk.props" />
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk.props" />
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk.props" />
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '10.0.16299.0'" Project="$(NugetPath)\Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\Microsoft.Net.Native.Compiler.props" />
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '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)' >= '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)' >= '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)' >= '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)' >= '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)' >= '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)' >= '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)' >= '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 ファイルの末尾で、終了Projectタグの直前に、次のコードを追加します (変更なし)。
<!-- Import all of the .NET Native / CoreCLR targets at the end of the project -->
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk.targets" />
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk.targets" />
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk.targets" />
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '10.0.16299.0'" Project="$(NugetPath)\Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\Microsoft.Net.Native.Compiler.targets" />
<Import Condition="'$(WindowsTargetPlatformMinVersion)' >= '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)' >= '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)' >= '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)' >= '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)' >= '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)' >= '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)' >= '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)' >= '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 projectのショートカット メニューを開き、[Project再読み込み] を選択します。
.NET ネイティブ用のビルド
.NET Native 向けにビルドされた C# コンポーネントを使用して、アプリケーションをビルドおよびテストすることをお勧めします。 Visual Studioで、CppToCSharpWinRT projectのショートカット メニューを開き、[アンロード] Projectを選択してテキスト エディターでCppToCSharpWinRT.vcxprojを開きます。
次に、 UseDotNetNativeToolchain プロパティを、C++ プロジェクト ファイルの Release 構成と Arm64 構成で true に設定します。
Visual Studio ソリューション エクスプローラーで、CppToCSharpWinRT projectのショートカット メニューを開き、[Projectの再読み込み] を選択します。
<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>
関連トピック
Windows developer