Compartir a través de


Creación de un componente de Windows Runtime de C# para su uso desde una aplicación de C++/WinRT

Este tema le guía por el proceso de agregar un componente de C# simple al proyecto de C++/WinRT.

Visual Studio facilita la creación e implementación de sus propios tipos personalizados de Windows Runtime dentro de un proyecto de componente de Windows Runtime (CMR) escrito con C# o Visual Basic y, a continuación, para hacer referencia a ese CMR desde un proyecto de aplicación de C++ y para consumir esos tipos personalizados de esa aplicación.

Internamente, los tipos de Windows Runtime pueden usar cualquier funcionalidad de .NET permitida en una aplicación para UWP.

Nota:

Para obtener más información, consulta "componentes de Windows Runtime con C# y Visual Basic" y ".NET para aplicaciones de UWP".

Externamente, los miembros de su tipo solo pueden exponer tipos de Windows Runtime para sus parámetros y valores devueltos. Cuando compilas tu solución, Visual Studio construye tu proyecto WRC de .NET y, a continuación, ejecuta un paso de compilación que crea un archivo de metadatos de Windows (.winmd). Este es tu componente de Windows Runtime (WRC), que Visual Studio incluye en tu aplicación.

Nota:

.NET asigna automáticamente algunos tipos de .NET usados habitualmente, como tipos de datos primitivos y tipos de colección, a sus equivalentes de Windows Runtime. Estos tipos de .NET se pueden usar en la interfaz pública de un componente de Windows Runtime y aparecerán a los usuarios del componente como los tipos de Windows Runtime correspondientes. Vea componentes de Windows Runtime con C# y Visual Basic.

Prerrequisitos

Crear una aplicación en blanco

En Visual Studio, cree un nuevo proyecto utilizando la plantilla de proyecto Aplicación en blanco (C++/WinRT). Asegúrese de que está utilizando la plantilla (C++/WinRT) y no la de (Universal Windows).

Establezca el nombre del nuevo proyecto en CppToCSharpWinRT para que la estructura de carpetas coincida con el tutorial.

Agregar un componente de Windows Runtime de C# a la solución

En Visual Studio, cree el proyecto de componente: en el Explorador de soluciones, abra el menú contextual de la solución CppToCSharpWinRT y elija Agregar y, a continuación, elija Nuevo proyecto para agregar un nuevo proyecto de C# a la solución. En la sección plantillas instaladas de del cuadro de diálogo Agregar nuevo proyecto cuadro de diálogo, elija visual C# y, a continuación, elija Windowsy, a continuación, universal. Elija la plantilla Componente de Windows Runtime (Windows Universal) y escriba SampleComponent para el nombre del proyecto.

Nota:

En el cuadro de diálogo Nuevo proyecto de la Plataforma universal de Windows , elija Windows 10 Creators Update (10.0; Compilación 15063) como versión mínima. Consulte la sección Versión Mínima de la Aplicación a continuación para obtener más información.

Adición del método GetMyString de C#

En el proyecto SampleComponent, cambie el nombre de la clase de Class1 a Ejemplo. A continuación, agregue dos miembros simples a la clase , un campo privado int y un método de instancia denominado GetMyString:

    public sealed class Example
    {
        int MyNumber;

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

Nota:

De forma predeterminada, la clase está marcada sellada y pública. Todas las clases de Windows Runtime que expongas del componente deben estar selladas.

Nota:

Opcional: Para habilitar IntelliSense para los miembros recién agregados, en el Explorador de soluciones, abra el menú contextual del proyecto SampleComponent, y, a continuación, elija Compilar.

Haga referencia al componente SampleComponent de C# desde el proyecto CppToCSharpWinRT

En el Explorador de soluciones, en el proyecto de C++/WinRT, abra el menú contextual de Referenciasy, a continuación, elija Agregar referencia para abrir el cuadro de diálogo Agregar referencia. Elija Proyectosy, después, elija Solución. Marque la casilla para el proyecto SampleComponent y elija Aceptar para agregar una referencia.

Nota:

Opcional: Para habilitar IntelliSense para el proyecto de C++/WinRT, en el Explorador de soluciones, abra el menú contextual del proyecto de CppToCSharpWinRT y, a continuación, elija Compilar.

Editar MainPage.h

Abra MainPage.h en el proyecto CppToCSharpWinRT y agregue dos elementos. En primer lugar, agregue #include "winrt/SampleComponent.h" al final de las #include instrucciones y, a continuación, un winrt::SampleComponent::Example campo a la MainPage estructura.

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

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

Nota:

En Visual Studio, MainPage.h aparece en MainPage.xaml.

Editar MainPage.cpp

En MainPage.cpp, cambie la Mainpage::ClickHandler implementación para llamar al método GetMyStringde C# .

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

    hstring myString = myExample.GetMyString();

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

Ejecución del proyecto

Ahora puede compilar y ejecutar el proyecto. Cada vez que haga clic en el botón, se incrementará el número del botón.

Captura de pantalla de Windows C++/WinRT llamando a un componente de C#

Sugerencia

En Visual Studio, cree el proyecto de componente: en el Explorador de soluciones, abra el menú contextual del proyecto de CppToCSharpWinRT y elija Propiedadesy luego seleccione Depuración en Propiedades de configuración. Establezca el tipo de depurador en Administrado y Nativo si desea depurar el código de C# (administrado) y C++ (nativo). Propiedades de depuración de C++

Versión mínima de la aplicación

La versión mínima de la aplicación del proyecto C# controlará la versión de .NET que se usa para compilar la aplicación. Por ejemplo, al elegir Windows 10 Fall Creators Update (10.0; La compilación 16299) o posterior habilitará la compatibilidad con procesadores .NET Standard 2.0 y Windows Arm64.

Sugerencia

Se recomienda utilizar las versiones de Application Minimum por debajo de la 16299 para evitar una configuración adicional en la compilación, si no se requiere compatibilidad con .NET Standard 2.0 o Arm64.

Configurar para Windows 10 Fall Creators Update (10.0; Compilación 16299)

Siga estos pasos para habilitar la compatibilidad con .NET Standard 2.0 o Windows Arm64 en los proyectos de C# a los que se hace referencia desde el proyecto de C++/WinRT.

En Visual Studio, vaya al Explorador de soluciones y abra el menú contextual del proyecto CppToCSharpWinRT . Elija Propiedades y establezca la versión mínima de la aplicación universal de Windows en Windows 10 Fall Creators Update (10.0; Compilación 16299) (o superior). Haga lo mismo para el proyecto SampleComponent.

En Visual Studio, abra el menú contextual del proyecto de CppToCSharpWinRT y elija Descargar Proyecto para abrir CppToCSharpWinRT.vcxproj en el editor de texto.

Copie y pegue el siguiente código XML en el primer 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 -->

Los valores de DotNetNativeVersion, DotNetNativeSharedLibraryy UWPCoreRuntimeSdkVersion pueden variar en función de la versión de Visual Studio. Para establecerlos en los valores correctos, abra %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages y examine el subdirectorio para cada valor de la tabla siguiente. El %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler directorio tendrá un subdirectorio que contiene una versión instalada de .NET nativa que comienza por 2.2. En el ejemplo siguiente, es 2.2.12-rel-31116-00.

Variable de MSBuild Directorio Ejemplo
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

Nota:

Hay varias arquitecturas admitidas para Microsoft.Net.Native.SharedLibrary. Reemplace x64 con la arquitectura adecuada. Por ejemplo, la arm64 arquitectura estaría en el %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-arm64.microsoft.net.native.sharedlibrary directorio .

A continuación, inmediatamente después del primer PropertyGroup, agregue lo siguiente (sin modificar).

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

Al final del archivo del proyecto, justo antes de la etiqueta de cierre Project , agregue lo siguiente (sin modificar).

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

Vuelva a cargar el archivo del proyecto en Visual Studio. Para ello, en el Explorador de soluciones de Visual Studio, abra el menú contextual del proyecto de CppToCSharpWinRT y elija Recargar proyecto.

Construcción para .NET Native

Se recomienda compilar y probar la aplicación con el componente de C# compilado con .NET native. En Visual Studio, abra el menú contextual del proyecto de CppToCSharpWinRT y elija Descargar Proyecto para abrir CppToCSharpWinRT.vcxproj en el editor de texto.

A continuación, establezca la UseDotNetNativeToolchain propiedad true en las configuraciones Release y Arm64 en el archivo de proyecto de C++.

En el Explorador de soluciones de Visual Studio, abra el menú contextual del proyecto de CppToCSharpWinRT y seleccione Recargar proyecto.

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

Hacer referencia a otros paquetes NuGet de C#

Si el componente de C# hace referencia a otros paquetes nuget , es posible que el archivo de proyecto de la aplicación necesite dependencias de archivo de lista del paquete nuget como contenido de implementación. Por ejemplo, si el componente de C# hace referencia al paquete nuget Newtonsoft.Json, también se debe hacer referencia al mismo paquete nuget y la misma dependencia de archivo en el proyecto de aplicación.

En el archivo SampleComponent.csproj , agregue la referencia del paquete nuget:

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

En el proyecto CppToCSharpWinRT, busque el archivo packages.config y agregue la referencia de NuGet adecuada. Esto instalará el paquete nuget en la carpeta del paquete de la solución.

En packages.config, agregue la misma referencia del paquete nuget:

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

A continuación, agregue lo siguiente al archivo de proyecto de aplicación para hacer referencia a la dependencia de archivo adecuada desde la carpeta del paquete de la solución. Por ejemplo, en CppToCSharpWinRT.vcxproj agregue lo siguiente:

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