Redigera en C#-Windows Runtime komponent för användning från en C++/WinRT-app

Det här avsnittet beskriver hur du lägger till en enkel C#-komponent i ditt C++/WinRT-projekt.

Visual Studio gör det enkelt att skapa och distribuera egna anpassade Windows Runtime-typer i ett Windows Runtime-komponentprojekt (WRC) som är skrivet i C# eller Visual Basic, och sedan referera till denna WRC-komponent från ett C++-programprojekt och använda dessa anpassade typer i programmet.

Internt kan dina Windows Runtime typer använda alla .NET funktioner som tillåts i ett UWP-program.

Externt kan medlemmarna i din typ endast exponera Windows Runtime typer för sina parametrar och returvärden. När du skapar din lösning skapar Visual Studio ditt .NET WRC-projekt och kör sedan ett byggsteg som skapar en Windows metadatafil (.winmd). Det här är din Windows Runtime komponent (WRC), som Visual Studio innehåller i din app.

Note

.NET mappar automatiskt vissa vanliga .NET typer, till exempel primitiva datatyper och samlingstyper, till deras Windows Runtime motsvarigheter. Dessa .NET typer kan användas i det offentliga gränssnittet för en Windows Runtime komponent och visas för komponentens användare som motsvarande Windows Runtime typer. Se Windows Runtime komponenter med C# och Visual Basic.

Förutsättningar

Skapa en tom app

I Visual Studio skapar du ett nytt projekt med hjälp av projektmallen Tom app (C++/WinRT) (för WinUI 3-skrivbordsappar använder du mallen Tom app, Paketerad (WinUI 3 i Desktop). Kontrollera att du använder mallen (C++/WinRT) och inte den (Universella Windows).

Ange namnet på det nya projektet till CppToCSharpWinRT så att mappstrukturen matchar genomgången.

Lägga till en C#-Windows Runtime komponent i lösningen

I Visual Studio skapar du komponenten project: I Prieskumník riešení öppnar du snabbmenyn för CppToCSharpWinRT-lösningen och väljer Lägg till och väljer sedan Ny Project för att lägga till en ny C#-project i lösningen. I avsnittet Installerade mallar i dialogrutan Lägg till ny Project väljer du Visual C# och sedan Windows och sedan Universell. Välj mallen Windows Runtime Component (Universal Windows) och ange SampleComponent som projektnamn.

Note

I dialogrutan Nytt Universell Windows-plattform Project väljer du Windows 10 Creators Update (10.0; Skapa 15063) som lägsta version. Mer information finns i avsnittet Programminimumversion nedan.

Lägg till metoden C# GetMyString

I SampleComponent-projektet ändrar du namnet på klassen från Klass1 till Exempel. Lägg sedan till två enkla medlemmar i klassen, ett privat int fält och en instansmetod med namnet GetMyString:

    public sealed class Example
    {
        int MyNumber;

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

Note

Som standard är klassen markerad som offentlig förseglad. Alla Windows Runtime klasser som du exponerar från komponenten måste vara förseglade.

Note

Valfritt: Om du vill aktivera IntelliSense för de nyligen tillagda medlemmarna öppnar du snabbmenyn för SampleComponent-projektet i Prieskumník riešení och väljer sedan Skapa.

Referera till C# SampleComponent från CppToCSharpWinRT-projektet

I Prieskumník riešení öppnar du snabbmenyn för Referenser i C++/WinRT-projektet och väljer sedan Lägg till referens för att öppna dialogrutan Lägg till referens. Välj Projekt och sedan Lösning. Markera kryssrutan för SampleComponent-projektet och välj OK för att lägga till en referens.

Note

Valfritt: Om du vill aktivera IntelliSense för C++/WinRT-projektet öppnar du snabbmenyn för CppToCSharpWinRT-projektet i Prieskumník riešení och väljer sedan Skapa.

Redigera MainPage.h

Öppna MainPage.h i CppToCSharpWinRT-projektet och lägg sedan till två objekt. Lägg först till #include "winrt/SampleComponent.h" i slutet av -uttrycken #include och sedan ett winrt::SampleComponent::Example fält i structen MainPage .

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

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

Note

I Visual Studio visas MainPage.h under MainPage.xaml.

Redigera MainPage.cpp

I MainPage.cppändrar du implementeringen Mainpage::ClickHandler för att anropa C#-metoden GetMyString.

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

    hstring myString = myExample.GetMyString();

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

Kör projektet

Nu kan du skapa och köra projektet. Varje gång du klickar på knappen ökar talet i knappen.

Skärmbild av C++/WinRT Windows-anrop till en C#-komponent

Tip

I Visual Studio skapar du komponentprojektet: I Prieskumník riešení öppnar du snabbmenyn för CppToCSharpWinRT-projektet och väljer Egenskaper och väljer sedan Felsökning under Konfigurationsegenskaper. Ange felsökartyp till Hanterad och intern om du vill felsöka både C# (hanterad) och C++ (intern) kod. Egenskaper för C++ felsökning

Lägsta version för program

Programminimum för C#-projektversionen styr versionen av .NET som används för att kompilera programmet. Du kan till exempel välja Windows 10 Fall Creators Update (10.0; Build 16299) eller senare aktiverar .NET Standard 2.0- och Windows Arm64-processorstöd.

Tip

Vi rekommenderar att du använder programminimumversioner som är lägre än 16299 för att undvika extra byggkonfiguration om .NET Standard 2.0- eller Arm64-stöd inte behövs.

Konfigurera för Windows 10 Fall Creators Update (10.0; version 16299)

Följ de här stegen för att aktivera stöd för .NET Standard 2.0 eller Windows Arm64 i C#-projekten som refereras från ditt C++/WinRT-projekt.

I Visual Studio går du till Prieskumník riešení och öppnar snabbmenyn för CppToCSharpWinRT-projektet. Välj Egenskaper och ange versionen Universal Windows App Min till Windows 10 Fall Creators Update (10.0; Build 16299) (eller senare). Gör samma sak för SampleComponent-projektet .

I Visual Studio öppnar du snabbmenyn för CppToCSharpWinRT-project och väljer Ta bort Project för att öppna CppToCSharpWinRT.vcxproj i textredigeraren.

Kopiera och klistra in följande XML till den första PropertyGroup i 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 -->

Värdena för DotNetNativeVersion, DotNetNativeSharedLibraryoch UWPCoreRuntimeSdkVersion kan variera beroende på vilken version av Visual Studio. För att ange dem till rätt värden öppnar du %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages och tittar i underkatalogen för varje värde i tabellen nedan. Katalogen %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler har en underkatalog som innehåller en installerad version av .NET som börjar med 2.2. I exemplet nedan är det 2.2.12-rel-31116-00.

MSBuild-variabel Katalog Example
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

Det finns flera arkitekturer som stöds för Microsoft. Net.Native.SharedLibrary. Ersätt x64 med lämplig arkitektur. Arkitekturen arm64 finns till exempel i %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-arm64.microsoft.net.native.sharedlibrary katalogen.

Lägg sedan till följande (oförändrad) direkt efter den första 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 -->

I slutet av project-filen, precis före den avslutande Project taggen, lägger du till följande (oförändrad).

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

Ladda om projektfilen i Visual Studio. Om du vill göra det öppnar du snabbmenyn för CppToCSharpWinRT-project i Visual Studio Prieskumník riešení och väljer Läs in Project igen.

Skapa för .NET native

Det rekommenderas att du bygger och testar din applikation med C#-komponenten som har byggts för .NET Native. I Visual Studio öppnar du snabbmenyn för CppToCSharpWinRT-project och väljer Ta bort Project för att öppna CppToCSharpWinRT.vcxproj i textredigeraren.

Ställ sedan in egenskapen UseDotNetNativeToolchaintrue i version- och Arm64-konfigurationerna i C++-projektfilen.

I Visual Studio Prieskumník riešení öppnar du snabbmenyn för CppToCSharpWinRT-project och väljer Läs in Project igen.

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

Referera till andra C#-nuget-paket

Om C#-komponenten refererar till andra nuget-paket kan programmets projektfil behöva listfilberoenden från nuget-paketet som distributionsinnehåll. Om C#-komponenten till exempel refererar till nuget-paketet Newtonsoft.Json bör samma nuget-paket och filberoende också refereras till i programprojektet.

Lägg till nuget-paketreferensen i filen SampleComponent.csproj :

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

Leta upp filen packages.config i CppToCSharpWinRT-projektet och lägg till lämplig nuget-referens. Nuget-paketet installeras i lösningens paketmapp.

I packages.configlägger du till samma nuget-paketreferens:

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

Lägg sedan till följande i programprojektfilen för att referera till lämpligt filberoende från lösningens paketmapp. Lägg till exempel till följande i 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>