Een C#-Windows Runtime-onderdeel ontwerpen voor gebruik vanuit een C++/WinRT-app

In dit onderwerp wordt u begeleid bij het toevoegen van een eenvoudig C#-onderdeel aan uw C++/WinRT-project.

Visual Studio maakt het eenvoudig om uw eigen aangepaste Windows Runtime typen te maken en te implementeren binnen een WRC-project (Windows Runtime component) dat is geschreven met C# of Visual Basic, en vervolgens naar die WRC te verwijzen vanuit een C++-toepassingsproject en om deze aangepaste typen van die toepassing te gebruiken.

Intern kunnen uw Windows Runtime typen elke .NET-functionaliteit gebruiken die is toegestaan in een UWP-toepassing.

Extern kunnen de leden van uw type alleen Windows Runtime typen weergeven voor hun parameters en retourwaarden. Wanneer u uw oplossing bouwt, bouwt Visual Studio uw .NET WRC-project en voert u vervolgens een buildstap uit waarmee een Windows metagegevensbestand (.winmd) wordt gemaakt. Dit is uw Windows Runtime-onderdeel (WRC), dat Visual Studio bevat in uw app.

Note

.NET wijst automatisch een aantal veelgebruikte .NET typen, zoals primitieve gegevenstypen en verzamelingstypen, toe aan hun Windows Runtime equivalenten. Deze .NET typen kunnen worden gebruikt in de openbare interface van een Windows Runtime onderdeel en worden weergegeven aan gebruikers van het onderdeel als de bijbehorende Windows Runtime typen. Zie Windows Runtime onderdelen met C# en Visual Basic.

Prerequisites

Een lege app maken

Maak in Visual Studio een nieuw project met de projectsjabloon Lege app (C++/WinRT) (voor WinUI 3-bureaublad-apps gebruik je de sjabloon Blank App, Packaged (WinUI 3 in Desktop)). Zorg ervoor dat u de sjabloon (C++/WinRT) gebruikt en niet de sjabloon (Universal Windows).

Stel de naam van het nieuwe project in op CppToCSharpWinRT , zodat de mapstructuur overeenkomt met het overzicht.

Een C#-Windows Runtime-onderdeel toevoegen aan de oplossing

Maak in Visual Studio het onderdeel project: Open in Solution Explorer het snelmenu voor de CppToCSharpWinRT-oplossing en kies Toevoegen en kies vervolgens Nieuw Project om een nieuwe C#-project toe te voegen aan de oplossing. Kies Visual C# in de sectie Geïnstalleerde sjablonen van het dialoogvenster Nieuwe Project toevoegen en kies vervolgens Windows en vervolgens Universeel. Kies de sjabloon Windows Runtime Component (Universal Windows) en voer SampleComponent in als projectnaam.

Note

Kies in het dialoogvenster Nieuw Universeel Windows-platform-project de optie Windows 10 Creators Update (10.0; Build 15063) als minimumversie. Zie de sectie Minimumversie van de toepassing hieronder voor meer informatie.

De methode C# GetMyString toevoegen

Wijzig in het SampleComponent-project de naam van de klasse van Class1 in Example. Voeg vervolgens twee eenvoudige leden toe aan de klasse, een privéveld int en een instantiemethode met de naam GetMyString:

    public sealed class Example
    {
        int MyNumber;

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

Note

De klasse is standaard gemarkeerd als openbaar verzegeld. Alle Windows Runtime klassen die u beschikbaar maakt vanuit uw onderdeel, moeten worden verzegeld.

Note

Optioneel: Als u IntelliSense wilt inschakelen voor de nieuw toegevoegde leden, opent u in Solution Explorer het snelmenu voor het SampleComponent-project en kiest u Vervolgens Build.

Verwijs naar C# SampleComponent vanuit het CppToCSharpWinRT-project

Open in Solution Explorer in het C++/WinRT-project het snelmenu voor Verwijzingen en kies Verwijzing toevoegen om het dialoogvenster Verwijzing toevoegen te openen. Kies Projecten en vervolgens Oplossing. Schakel het selectievakje voor het SampleComponent-project in en kies OK om een verwijzing toe te voegen.

Note

Optioneel: Als u IntelliSense wilt inschakelen voor het C++/WinRT-project, opent u in Solution Explorer het snelmenu voor het CppToCSharpWinRT-project en kiest u Vervolgens Build.

MainPage.h bewerken

Open MainPage.h het CppToCSharpWinRT-project en voeg vervolgens twee items toe. #include "winrt/SampleComponent.h" Voeg eerst aan het einde van de #include instructies en vervolgens een winrt::SampleComponent::Example veld toe aan de MainPage struct.

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

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

Note

In Visual Studio wordt MainPage.h vermeld onder MainPage.xaml.

MainPage.cpp bewerken

Wijzig in MainPage.cpp de implementatie van Mainpage::ClickHandler om de C#-methode GetMyString aan te roepen.

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

    hstring myString = myExample.GetMyString();

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

Het project uitvoeren

U kunt nu de project bouwen en uitvoeren. Telkens wanneer u op de knop klikt, wordt het nummer in de knop verhoogd.

Screenshot van C++/WinRT Windows die een C#-component aanroept

Hint

Maak in Visual Studio het onderdeelproject: Open in Solution Explorer het snelmenu voor het CppToCSharpWinRT-project en kies Eigenschappen en kies Vervolgens Foutopsporing onder Configuratie-eigenschappen. Stel het foutopsporingsprogrammatype in op Beheerd en Systeemeigen als u fouten wilt opsporen in zowel de C#-code (beheerd) als C++ (systeemeigen). Eigenschappen van C++ foutopsporing

Minimale appversie

Het minimale toepassingsniveau van de C#-projectversie bepaalt welke versie van .NET wordt gebruikt om de toepassing te compileren. Kies bijvoorbeeld Windows 10 Fall Creators Update (10.0; Build 16299) of hoger maakt ondersteuning voor .NET Standard 2.0 en Windows Arm64-processor mogelijk.

Hint

We raden u aan om minimale versies van toepassingen te gebruiken die lager zijn dan 16299 om extra buildconfiguratie te voorkomen als .NET Standard 2.0- of Arm64-ondersteuning niet nodig is.

Configureren voor Windows 10 Fall Creators Update (10.0; Build 16299)

Volg deze stappen om .NET Standard 2.0 of Windows Arm64-ondersteuning in te schakelen in de C#-projecten waarnaar wordt verwezen vanuit uw C++/WinRT-project.

Ga in Visual Studio naar het Solution Explorer en open het snelmenu voor het project CppToCSharpWinRT. Kies Eigenschappen en stel de Universal Windows-app Min-versie in op Windows 10 Fall Creators Update (10.0; Build 16299) (of hoger). Doe hetzelfde voor het SampleComponent-project .

Open in Visual Studio het snelmenu voor het project CppToCSharpWinRT en kies Project ontladen om CppToCSharpWinRT.vcxproj in de teksteditor te openen.

Kopieer en plak de volgende XML naar de eerste PropertyGroup in 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 -->

De waarden voor DotNetNativeVersion, DotNetNativeSharedLibraryen UWPCoreRuntimeSdkVersion kunnen variëren, afhankelijk van de versie van Visual Studio. Om deze op de juiste waarden in te stellen, opent u %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages en bekijkt u de submap die bij elke waarde in de onderstaande tabel hoort. De %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler map heeft een submap die een geïnstalleerde versie van .NET systeemeigen versie bevat die begint met 2.2. In het onderstaande voorbeeld is dat 2.2.12-rel-31116-00.

MSBuild-variabele Directory Voorbeeld
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

Note

Er zijn meerdere ondersteunde architecturen voor Microsoft. Net.Native.SharedLibrary. Vervang x64 door de juiste architectuur. De arm64 architectuur bevindt zich bijvoorbeeld in de %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-arm64.microsoft.net.native.sharedlibrary map.

Voeg vervolgens direct na de eerste PropertyGrouphet volgende toe (ongewijzigd).

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

Voeg aan het einde van het project-bestand, net voor de afsluitende Project tag, het volgende toe (ongewijzigd).

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

Laad het projectbestand opnieuw in Visual Studio. Hiervoor opent u in de Visual Studio Solution Explorer het snelmenu voor de CppToCSharpWinRT-project en kiest u Reload Project.

Compileren voor .NET Native

Het wordt aanbevolen uw toepassing te bouwen en te testen met de C#-component die is gebouwd voor .NET Native. Open in Visual Studio het snelmenu voor het project CppToCSharpWinRT en kies Project ontladen om CppToCSharpWinRT.vcxproj in de teksteditor te openen.

Stel vervolgens de eigenschap UseDotNetNativeToolchain in op true de release- en Arm64-configuraties in het C++-projectbestand.

Open in de Visual Studio Solution Explorer het snelmenu voor de CppToCSharpWinRT-project en kies Reload Project.

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

Verwijzen naar andere C#-nuget-pakketten

Als het C#-onderdeel verwijst naar andere nuget-pakketten, heeft het projectbestand van de toepassing mogelijk lijstbestandsafhankelijkheden van het nuget-pakket nodig als implementatie-inhoud. Als het C#-onderdeel bijvoorbeeld verwijst naar het NuGet-pakket Newtonsoft.Json, moet ook naar hetzelfde nuget-pakket en dezelfde bestandsafhankelijkheid worden verwezen in het toepassingsproject.

Voeg in het bestand SampleComponent.csproj de nuget-pakketreferentie toe:

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

Zoek in het CppToCSharpWinRT-project het packages.config-bestand en voeg de juiste nuget-verwijzing toe. Hiermee wordt het nuget-pakket geïnstalleerd in de pakketmap van de oplossing.

Voeg in packages.configdezelfde nuget-pakketreferentie toe:

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

Voeg vervolgens het volgende toe aan het toepassingsprojectbestand om te verwijzen naar de juiste bestandsafhankelijkheid uit de pakketmap van de oplossing. Voeg bijvoorbeeld in CppToCSharpWinRT.vcxproj het volgende toe:

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