Création d’un composant Windows Runtime C# à utiliser à partir d’une application C++/WinRT
Cette rubrique vous montre pas à pas comment ajouter un composant C# simple à un projet C++/WinRT.
Visual Studio vous aide à créer et déployer vos propres types Windows Runtime personnalisés dans un projet de composant Windows Runtime (WRC) écrit en C# ou Visual Basic, puis à référencer ce WRC à partir d’un projet d’application C++ et à utiliser ces types personnalisés dans cette application.
En interne, vos types Windows Runtime peuvent utiliser toutes les fonctionnalités .NET qui sont autorisées dans une application Windows universelle (UWP).
Notes
Pour plus d’informations, consultez Composants Windows Runtime avec C# et Visual Basic et Présentation de .NET pour les applications UWP.
En externe, les membres de votre type peuvent exposer uniquement les types Windows Runtime pour leurs paramètres et valeurs de retour. Quand vous générez votre solution, Visual Studio génère votre projet .NET WRC, puis exécute une étape de génération qui crée un fichier de métadonnées Windows (.winmd). Il s’agit de votre composant Windows Runtime (WRC), que Visual Studio inclut dans votre application.
Notes
.NET mappe automatiquement certains types .NET couramment utilisés, tels que les types de données primitifs et les types de collection, à leurs équivalents Windows Runtime. Ces types .NET peuvent être utilisés dans l’interface publique d’un composant Windows Runtime et sont présentés aux utilisateurs du composant comme les types Windows Runtime correspondants. Consultez Composants Windows Runtime avec C# et Visual Basic.
Prérequis
- Windows 10
- Microsoft Visual Studio
Créer une application vide
Dans Visual Studio, créez un projet à l’aide du modèle de projet Blank App (C++/WinRT) . Veillez à utiliser le modèle (C++/WinRT) , et non le modèle (Windows universel) .
Nommez le nouveau projet CppToCSharpWinRT afin que votre structure de dossiers corresponde à la procédure pas à pas.
Ajouter un composant Windows Runtime C# à la solution
Dans Visual Studio, créez le projet de composant : dans l’Explorateur de solutions, ouvrez le menu contextuel de la solution CppToCSharpWinRT. Ensuite, choisissez Ajouter, puis Nouveau projet pour ajouter un nouveau projet C# à la solution. Dans la section Modèles installés de la boîte de dialogue Ajouter un nouveau projet, choisissez Visual C# , puis choisissez Windows et Universel. Choisissez le modèle Composant Windows Runtime (Universal Windows) et nommez le projet SampleComponent.
Notes
Dans la boîte de dialogue Nouveau projet de plateforme Windows universelle, choisissez Windows 10 Creators Update (10.0 ; Build 15063) comme version minimale. Pour plus d’informations, consultez la section Version minimale de l’application ci-dessous.
Ajouter la méthode GetMyString C#
Dans le projet SampleComponent, changez le nom de la classe de Class1 en Example. Ajoutez ensuite deux membres simples à la classe, un champ int
privé et une méthode d’instance nommée GetMyString :
public sealed class Example { int MyNumber; public string GetMyString() { return $"This is call #: {++MyNumber}"; } }
Notes
Par défaut, la classe est marquée comme public sealed. Toutes les classes Windows Runtime que vous exposez à partir de votre composant doivent être sealed.
Notes
Facultatif : pour activer IntelliSense pour les membres récemment ajoutés, dans l’Explorateur de solutions, ouvrez le menu contextuel du projet SampleComponent, puis choisissez Générer.
Référencer le SampleComponent C# à partir du projet CppToCSharpWinRT
Dans l’Explorateur de solutions, dans le projet C++/WinRT, ouvrez le menu contextuel de Références, puis choisissez Ajouter une référence pour ouvrir la boîte de dialogue Ajouter une référence. Sélectionnez Projets, puis Solution. Cochez la case du projet SampleComponent et choisissez OK pour ajouter une référence.
Notes
Facultatif : pour activer IntelliSense pour le projet C++/WinRT, dans l’Explorateur de solutions, ouvrez le menu contextuel du projet CppToCSharpWinRT, puis choisissez Générer.
Modifier MainPage.h
Ouvrez MainPage.h
dans le projet CppToCSharpWinRT, puis ajoutez deux éléments. Ajoutez tout d’abord #include "winrt/SampleComponent.h"
à la fin des instructions #include
, puis ajoutez un champ winrt::SampleComponent::Example
à la structure MainPage
.
// MainPage.h
...
#include "winrt/SampleComponent.h"
namespace winrt::CppToCSharpWinRT::implementation
{
struct MainPage : MainPageT<MainPage>
{
...
winrt::SampleComponent::Example myExample;
...
};
}
Notes
Dans Visual Studio, MainPage.h
est listé sous MainPage.xaml
.
Modifier MainPage.cpp
Dans MainPage.cpp
, modifiez l’implémentation de Mainpage::ClickHandler
pour appeler la méthode C# GetMyString
.
void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
//myButton().Content(box_value(L"Clicked"));
hstring myString = myExample.GetMyString();
myButton().Content(box_value(myString));
}
Exécuter le projet
Vous pouvez à présent lancer le processus de génération et exécuter le projet. Chaque fois que vous cliquez sur le bouton, le nombre sur le bouton est incrémenté.
Conseil
Dans Visual Studio, créez le projet de composant : dans l’Explorateur de solutions, ouvrez le menu contextuel du projet CppToCSharpWinRT. Ensuite, choisissez Propriétés, puis choisissez Débogage sous Propriétés de configuration. Définissez le type de débogueur sur Managé et natif si vous souhaitez déboguer à la fois le code C# (managé) et le code C++ (natif).
Version minimale de l’application
La version minimale de l’application du projet C# contrôlera la version de .NET utilisée pour compiler l’application. Par exemple, le choix de Windows 10 Fall Creators Update (10.0 ; Build 16299) ou ultérieur permettra la prise en charge des processeurs NET Standard 2.0 et Windows Arm64.
Conseil
Nous vous recommandons d’utiliser des versions minimales d’application antérieures à la build 16299 pour éviter une configuration de build supplémentaire si la prise en charge de .NET Standard 2.0 ou Arm64 n’est pas nécessaire.
Configurer pour Windows 10 Fall Creators Update (10.0 ; Build 16299)
Effectuez les étapes suivantes pour activer la prise en charge de .NET Standard 2.0 ou Windows Arm64 dans les projets C# référencés à partir de votre projet C++/WinRT.
Dans Visual Studio, accédez à l’Explorateur de solutions et ouvrez le menu contextuel du projet CppToCSharpWinRT. Choisissez Propriétés et définissez la version minimale de l’application Windows universelle sur Windows 10 Fall Creators Update (10.0 ; Build 16299) (ou une version ultérieure). Faites la même chose pour le projet SampleComponent.
Dans Visual Studio, ouvrez le menu contextuel du projet CppToCSharpWinRT et choisissez Décharger le projet pour ouvrir CppToCSharpWinRT.vcxproj
dans l’éditeur de texte.
Copiez et collez le code XML suivant dans le premier PropertyGroup
dans 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 -->
Les valeurs de DotNetNativeVersion
, DotNetNativeSharedLibrary
et UWPCoreRuntimeSdkVersion
peuvent varier selon la version de Visual Studio. Pour attribuer les valeurs correctes, ouvrez %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages
et examinez le sous-répertoire pour chaque valeur dans le tableau ci-dessous. Le répertoire %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler
contient un sous-répertoire qui contient lui-même une version installée de .NET Native qui commence par 2.2
. Dans l’exemple ci-dessous, c’est 2.2.12-rel-31116-00
.
Variable MSBuild Répertoire Exemple 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
Notes
Il existe plusieurs architectures prises en charge pour Microsoft.Net.Native.SharedLibrary. Remplacez x64
par l’architecture appropriée. Par exemple, l’architecture arm64
se trouverait dans le répertoire %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-arm64.microsoft.net.native.sharedlibrary
.
Ensuite, immédiatement après le premier PropertyGroup
, ajoutez le code suivant (non modifié).
<!-- 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 -->
À la fin du fichier projet, juste avant la balise de fermeture Project
, ajoutez le code suivant (non modifié).
<!-- 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 -->
Rechargez le fichier projet dans Visual Studio. Pour ce faire, dans l’Explorateur de solutions Visual Studio, ouvrez le menu contextuel du projet CppToCSharpWinRT et choisissez Recharger le projet.
Génération pour .NET Native
Il est recommandé de générer et de tester votre application avec le nouveau composant C# sur .NET Native. Dans Visual Studio, ouvrez le menu contextuel du projet CppToCSharpWinRT et choisissez Décharger le projet pour ouvrir CppToCSharpWinRT.vcxproj
dans l’éditeur de texte.
Ensuite, définissez la propriété UseDotNetNativeToolchain
sur la valeur true
dans les configurations Release et Arm64 dans le fichier projet C++.
Dans l’Explorateur de solutions Visual Studio, ouvrez le menu contextuel du projet CppToCSharpWinRT et choisissez Recharger le projet.
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
...
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Platform)'=='Arm64'" Label="Configuration">
<UseDotNetNativeToolchain Condition="'$(UseDotNetNativeToolchain)'==''">true</UseDotNetNativeToolchain>
</PropertyGroup>
Référencement d’autres packages NuGet C#
Si le composant C# référence d’autres packages NuGet, le fichier projet de l’application peut avoir besoin de lister les dépendances de fichiers du package NuGet en tant que contenu de déploiement. Par exemple, si le composant C# fait référence au package NuGet Newtonsoft.Json, le même package NuGet et la même dépendance de fichier doivent aussi être référencés dans le projet d’application.
Dans le fichier SampleComponent.csproj, ajoutez la référence du package NuGet :
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.1</Version>
</PackageReference>
Dans le projet CppToCSharpWinRT, recherchez le fichier packages.config et ajoutez la référence NuGet appropriée. Ceci va installer le package NuGet dans le dossier de package de la solution.
Dans packages.config, ajoutez la référence du package NuGet :
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="native" developmentDependency="true" />
Ajoutez ensuite ceci au fichier projet de l’application pour référencer la dépendance de fichier appropriée à partir du dossier de package de la solution. Par exemple, dans CppToCSharpWinRT.vcxproj, ajoutez ceci :
<ItemGroup>
<None Include="..\packages\Newtonsoft.Json.13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll">
<Link>%(Filename)%(Extension)</Link>
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>