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 inom ett Windows Runtime-komponentprojekt (WRC) skrivet med C# eller Visual Basic, för att sedan referera till WRC från ett C++-applikationsprojekt och att använda de anpassade typerna från det 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 returnera vä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.

Anmärkning

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

Förutsättningar

Skapa en tom app

Skapa ett nytt projekt i Visual Studio med hjälp av Tom applikation (C++/WinRT) projektmall. 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 komponentprojektet: I Solution Explorer öppnar du snabbmenyn för CppToCSharpWinRT-lösningen och väljer Lägg till och väljer sedan Nytt projekt för att lägga till ett nytt C#-projekt i lösningen. I avsnittet Installerade mallar i dialogrutan Lägg till nytt projekt väljer du Visual C# och sedan Windows och sedan Universell. Välj mallen Windows Runtime Component (Universal Windows) och ange SampleComponent som projektnamn.

Anmärkning

I dialogrutan Nytt universellt Windows-plattformsprojekt 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}";
        }
    }

Anmärkning

Som standard markeras klassen public sealed. Alla Windows Runtime-klasser som du exponerar från komponenten måste vara förseglade.

Anmärkning

Valfritt: Om du vill aktivera IntelliSense för de nyligen tillagda medlemmarna öppnar du snabbmenyn för SampleComponent-projektet i Solution Explorer och väljer sedan Skapa.

Referera till C# SampleComponent från CppToCSharpWinRT-projektet

Öppna snabbmenyn för Referenser i Projektet C++/WinRT i Solution Explorer och välj sedan Lägg till referens för att öppna dialogrutan Lägg till referens . Välj Projects, och välj sedan Solution. Markera kryssrutan för SampleComponent-projektet och välj OK för att lägga till en referens.

Anmärkning

Valfritt: Om du vill aktivera IntelliSense för C++/WinRT-projektet öppnar du snabbmenyn för CppToCSharpWinRT-projektet i Solution Explorer 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;
...
    };
}

Anmärkning

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.

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

Tips/Råd

I Visual Studio skapar du komponentprojektet: I Solution Explorer ö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

Den applikationsminimum för C#-projektversionen styr den version av .NET som används för att kompilera applikationen. 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.

Tips/Råd

Vi rekommenderar att använda tillämpningsversioner lägre än 16299 för att undvika extra build-konfiguration om .NET Standard 2.0 eller Arm64-stöd inte är nödvändigt.

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

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

I Visual Studio går du till Solution Explorer och öppnar snabbmenyn för CppToCSharpWinRT-projektet . Välj Egenskaper och ange den universella Windows App Min-versionen 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 projektet CppToCSharpWinRT och väljer Ladda ur projekt 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å versionen av Visual Studio. Om du vill ange rätt värden, öppna %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages och titta på 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 native som börjar med 2.2. I exemplet nedan är det 2.2.12-rel-31116-00.

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

Anmärkning

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 projektfilen, 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 in projektfilen igen i Visual Studio. Det gör du genom att öppna snabbmenyn i Visual Studio Solution Explorer för CppToCSharpWinRT--projektet och välja Ladda om projektet.

Skapa för .NET Native

Vi rekommenderar att du skapar och testar ditt program med C#-komponenten som skapats mot .NET native. I Visual Studio öppnar du snabbmenyn för projektet CppToCSharpWinRT och väljer Ladda ur projekt för att öppna CppToCSharpWinRT.vcxproj i textredigeraren.

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

Öppna snabbmenyn för projektet CppToCSharpWinRT i Visual Studio Lösningsutforskaren och välj Ladda om projekt.

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