Partager via


Création d’un composant Windows Runtime C# à utiliser à partir d’une application C++/WinRT

Cette rubrique vous guide tout au long du processus d’ajout d’un composant C# simple à votre projet C++/WinRT.

Visual Studio facilite la création et le déploiement de vos propres types Windows Runtime personnalisés à l’intérieur d’un projet WRC (Windows Runtime Component) écrit avec C# ou Visual Basic, puis de référencer ce WRC à partir d’un projet d’application C++ et d’utiliser ces types personnalisés à partir de cette application.

En interne, vos types Windows Runtime peuvent utiliser toutes les fonctionnalités .NET autorisées dans une application UWP.

Remarque

Pour plus d’informations, consultez le composant Windows Runtime avec C# et Visual Basic et l'aperçu 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 leurs valeurs de retour. Lorsque vous générez votre solution, Visual Studio génère votre projet WRC .NET, 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.

Remarque

.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 apparaissent aux utilisateurs du composant en tant que types Windows Runtime correspondants. Consultez composants Windows Runtime avec C# et Visual Basic.

Conditions préalables

Créer une application vide

Dans Visual Studio, créez un nouveau projet à l'aide du modèle de projet Application Vide (C++/WinRT). Assurez-vous que vous utilisez le modèle (C++/WinRT), et non le modèle (Windows universel).

Définissez le nom du nouveau projet sur 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 , puis choisissez Ajouter, puis choisissez 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 Windows, puis Universal. Choisissez le modèle Composant Windows Runtime (Windows universel) et entrez SampleComponent pour le nom du projet.

Remarque

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 C# GetMyString

Dans le projet SampleComponent , remplacez le nom de la classe de Class1 par Example. Ajoutez ensuite deux membres simples à la classe, un champ privé int et une méthode d’instance nommée GetMyString :

    public sealed class Example
    {
        int MyNumber;

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

Remarque

Par défaut, la classe est marquée publique scellée. Toutes les classes Windows Runtime que vous exposez à partir de votre composant doivent être scellées.

Remarque

Facultatif : pour activer IntelliSense pour les membres nouvellement ajoutés, dans l’Explorateur de solutions, ouvrez le menu contextuel du projet SampleComponent , puis choisissez Générer.

Référencez le SampleComponent C# à partir du projet CppToCSharpWinRT

Dans l’Explorateur de solutions, dans le projet C++/WinRT, ouvrez le menu contextuel des références, puis choisissez Ajouter une référence pour ouvrir la boîte de dialogue Ajouter une référence . Choisissez Projets, puis Solution. Cochez la case pour le projet SampleComponent et choisissez OK pour ajouter une référence.

Remarque

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 le projet CppToCSharpWinRT , puis ajoutez deux éléments. Commencez par ajouter #include "winrt/SampleComponent.h" à la fin des #include instructions, puis un winrt::SampleComponent::Example champ au MainPage struct.

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

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

Remarque

Dans Visual Studio, MainPage.h est répertorié sous MainPage.xaml.

Modifier MainPage.cpp

Dans MainPage.cpp, modifiez l’implémentation Mainpage::ClickHandler pour appeler la méthode GetMyStringC#.

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 maintenant générer et exécuter le projet. Chaque fois que vous cliquez sur le bouton, le nombre dans le bouton est incrémenté.

Appel d'un composant C# via Windows C++/WinRT capture d’écran

Conseil / Astuce

Dans Visual Studio, créez le projet de composant : dans l’Explorateur de solutions, ouvrez le menu contextuel du projet CppToCSharpWinRT , puis choisissez Propriétés, puis choisissez Débogage sous Propriétés de configuration. Définissez le type de débogueur sur Managed and Native si vous souhaitez déboguer le code C# (managé) et C++ (natif). Propriétés de débogage C++

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, choisir Windows 10 Fall Creators Update (10.0 ; La build 16299) ou ultérieure active la prise en charge du processeur .NET Standard 2.0 et Windows Arm64.

Conseil / Astuce

Nous vous recommandons d’utiliser version minimale de l’application inférieure à 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)

Suivez ces étapes 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 min de l’application Windows universelle sur Windows 10 Fall Creators Update (10.0 ; Build 16299) (ou version ultérieure). Procédez de la même façon 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 de 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 pour DotNetNativeVersion, DotNetNativeSharedLibraryet UWPCoreRuntimeSdkVersion peuvent varier en fonction de la version de Visual Studio. Pour les définir sur les valeurs correctes, ouvrez le %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages et consultez le sous-répertoire correspondant à chaque valeur du tableau ci-dessous. Le %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler répertoire aura un sous-répertoire qui contient une version installée de .NET native qui commence par 2.2. Dans l’exemple ci-dessous, il s’agit 2.2.12-rel-31116-00de .

MSBuild Variable 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

Remarque

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 %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-arm64.microsoft.net.native.sharedlibrary répertoire.

Ensuite, immédiatement après la première PropertyGroup, ajoutez ce qui suit tel quel.

  <!-- 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 -->

À la fin du fichier projet, juste avant la balise de fermeture Project , ajoutez les éléments suivants (non inchangés).

  <!-- 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 -->

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.

Construction pour .NET Native

Il est recommandé de générer et de tester votre application avec le composant C# créé 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 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 paquets NuGet C#

Si le composant C# fait référence à d’autres packages nuget, le fichier projet de l’application peut avoir besoin de dépendances de fichier de liste à partir 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 également ê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. Cela installe le package nuget dans le dossier de package de la solution.

Dans packages.config, ajoutez la même référence de package nuget :

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

Ajoutez ensuite ce qui suit au fichier projet d’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 les éléments suivants :

  <ItemGroup>
    <None Include="..\packages\Newtonsoft.Json.13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll">
      <Link>%(Filename)%(Extension)</Link>
      <DeploymentContent>true</DeploymentContent>
    </None>
  </ItemGroup>