Componentes de Windows Runtime con C++/WinRT
En este tema se muestra cómo usar C++/WinRT para crear y consumir un componente de tiempo de ejecución de Windows, un componente al que se puede llamar desde una aplicación universal Windows creada con cualquier lenguaje Windows Runtime.
Hay varias razones para crear un componente Windows runtime en C++/WinRT.
- Para disfrutar de la ventaja de rendimiento de C++ en operaciones complejas o computacionalmente intensivas.
- Para reutilizar código estándar de C++ que ya está escrito y probado.
- Para exponer la funcionalidad win32 a una aplicación de plataforma Windows universal (UWP) escrita en, por ejemplo, C#.
En general, al crear el componente de C++/WinRT, puede usar tipos de la biblioteca estándar de C++ y tipos integrados, excepto en el límite de la interfaz binaria de aplicación (ABI) donde pasa datos hacia y desde código en otro .winmd paquete. En la ABI, use los tipos Windows runtime. Además, en el código de C++/WinRT, use tipos como delegado y evento para implementar eventos que se pueden generar desde el componente y controlarse en otro lenguaje. Vea C++/WinRT para obtener más información sobre C++/WinRT.
El resto de este tema le guía a través de cómo crear un componente de tiempo de ejecución de Windows en C++/WinRT y, a continuación, cómo consumirlo desde una aplicación.
El Windows runtime que se va a compilar en este tema contiene una clase en tiempo de ejecución que representa un termómetro. En el tema también se muestra una aplicación principal que consume la clase en tiempo de ejecución del termómetro y llama a una función para ajustar la temperatura.
Nota
Para más información sobre cómo instalar y usar C++/WinRT Visual Studio Extension (VSIX) y el paquete de NuGet (que juntos proporcionan la plantilla de proyecto y compatibilidad de la compilación), consulta Compatibilidad de Visual Studio para C++/WinRT.
Importante
Para conocer los conceptos y términos esenciales que te ayuden a entender cómo consumir y crear clases en tiempo de ejecución con C++/WinRT, consulta Consumir API con C++/WinRT y Crear API con C++/WinRT .
Crear un componente Windows Runtime (ThermometerWRC)
Para empezar, crea un proyecto en Microsoft Visual Studio. Cree un proyecto Windows Runtime Component (C++/WinRT) y asímbralo ThermometerWRC (para "termómetro Windows runtime"). Asegúrese de que la opción Colocar la solución y el proyecto en el mismo directorio esté desactivada. Elija como destino la versión más reciente disponible de manera general (es decir, no en versión preliminar) de Windows SDK. El nombre del proyecto ThermometerWRC le dará la experiencia más fácil con el resto de los pasos de este tema.
No compile aún el proyecto.
El proyecto recién creado contiene un archivo llamado Class.idl. En el Explorador de soluciones, cambie el nombre del archivo Thermometer.idl (al cambiar el nombre del archivo .idl, se cambia automáticamente el nombre de los archivos .h y .cpp dependientes). Reemplaza el contenido de Thermometer.idl por la lista siguiente.
// Thermometer.idl
namespace ThermometerWRC
{
runtimeclass Thermometer
{
Thermometer();
void AdjustTemperature(Single deltaFahrenheit);
};
}
Guarde el archivo. El proyecto no se compilará hasta completarse en este momento, pero compilar ahora es útil porque genera los archivos de código fuente en los que implementará la clase en tiempo de ejecución De termómetro. Así que puedes compilar ahora. En esta fase, verás errores de compilación porque no se han encontrado Class.h y Class.g.h.
Durante el proceso de compilación, la herramienta midl.exe se ejecuta para crear el archivo de metadatos de Windows Runtime de tu componente, que es \ThermometerWRC\Debug\ThermometerWRC\ThermometerWRC.winmd. Después se ejecutará la herramienta cppwinrt.exe (con la opción -component) para generar archivos de código fuente y ayudarte a crear tu componente. Estos archivos incluyen códigos auxiliares para empezar a implementar la clase en tiempo de ejecución De termómetro que declaró en el IDL. Estos archivos de código auxiliar son \ThermometerWRC\ThermometerWRC\Generated Files\sources\Thermometer.h y Thermometer.cpp.
Haz clic con el botón derecho en el nodo del proyecto y haz clic en Abrir carpeta en el Explorador de archivos. Se abre la carpeta del proyecto en el Explorador de archivos. Allí, copia los archivos de código auxiliar Thermometer.h y Thermometer.cpp desde la carpeta \ThermometerWRC\ThermometerWRC\Generated Files\sources\ en la carpeta que contiene los archivos de proyecto, que es \ThermometerWRC\ThermometerWRC\, y reemplaza los archivos que hay en el destino. Ahora, vamos a abrir Thermometer.h y Thermometer.cpp e implementar nuestra clase en tiempo de ejecución. En Thermometer.h , agregue un nuevo miembro privado a la implementaciónThermometer.h implementación de fábrica) del termómetro.
// Thermometer.h
...
namespace winrt::ThermometerWRC::implementation
{
struct Thermometer : ThermometerT<Thermometer>
{
...
private:
float m_temperatureFahrenheit { 0.f };
};
}
...
En Thermometer.cpp , implemente Thermometer.cpp como se muestra en la lista siguiente.
// Thermometer.cpp
...
namespace winrt::ThermometerWRC::implementation
{
void Thermometer::AdjustTemperature(float deltaFahrenheit)
{
m_temperatureFahrenheit += deltaFahrenheit;
}
}
Verá static_assert en la parte superior de Thermometer.h y Thermometer.cpp, que deberás quitar. Ahora se compilará el proyecto.
Si alguna advertencia impide la compilación, resácelas o establezca la propiedad del proyecto C/C++GeneralTreat Warnings As Errors(/WX-) en No (/WX-)y vuelva a compilar el proyecto.
Creación de una aplicación principal (ThermometerCoreApp) para probar el componente Windows Runtime
Ahora cree un nuevo proyecto (ya sea en la solución De termómetroWRC o en uno nuevo). Cree un proyecto de aplicación principal (C++/WinRT) y así mismo den el nombre DenúcleoCoreApp. Establezca ThermometerCoreApp como proyecto de inicio si los dos proyectos están en la misma solución.
Nota
Como se mencionó anteriormente, el archivo de metadatos de Windows Runtime para el componente de tiempo de ejecución de Windows (cuyo proyecto llamó a ThermometerWRC)se crea en la carpeta . El primer segmento de esa ruta de acceso es el nombre de la carpeta que contiene el archivo de solución; el siguiente segmento es el subdirectorio de la que se denomina Debug; y el último segmento es el subdirectorio de la asignada para el componente de Windows Runtime. Si no ha especificado el nombre Del termómetro del proyectoWRC, el archivo de metadatos estará en la carpeta .
Ahora, en el proyecto de aplicación principal(ThermometerCoreApp),agregue una referencia y vaya a (o agregue una referencia de proyecto a proyecto, si los dos proyectos están en la misma solución). Haz clic en Agregar y después en Aceptar. Ahora compile ThermometerCoreApp. En el improbable caso de que vea un error de que el archivo de carga no existe, excluya ese archivo del proyecto de componente del entorno de ejecución de Windows, vuelva a generarlo y, a continuación, vuelva a generar readme.txtreadme.txt
Durante el proceso de compilación, la herramienta cppwinrt.exe se ejecutará para procesar el archivo .winmd al que se hace referencia en los archivos de código fuente que contienen tipos proyectados para ayudarte a consumir tu componente. El encabezado de los tipos proyectados para las clases en tiempo de ejecución del componente, denominado ThermometerWRC.h , se genera en la carpeta \ThermometerCoreApp\ThermometerCoreApp\Generated Files\winrt\ .
Incluye dicho encabezado en App.cpp.
// App.cpp
...
#include <winrt/ThermometerWRC.h>
...
También en , agregue el código siguiente para crear una instancia de un objeto De termómetro (mediante el constructor predeterminado del tipo proyectado) y llame a un método en el App.cpp objeto App.cpp termómetro.
struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
ThermometerWRC::Thermometer m_thermometer;
...
void OnPointerPressed(IInspectable const &, PointerEventArgs const & args)
{
m_thermometer.AdjustTemperature(1.f);
...
}
...
};
Cada vez que haga clic en la ventana, incrementará la temperatura del objeto de termómetro. Puede establecer puntos de interrupción si desea seguir paso a paso el código para confirmar que la aplicación está llamando realmente al componente Windows Runtime.
Pasos siguientes
Para agregar aún más funcionalidad, o nuevos tipos de Windows Runtime, al componente C++/WinRT Windows Runtime, puede seguir los mismos patrones mostrados anteriormente. En primer lugar, use IDL para definir la funcionalidad que desea exponer. A continuación, compile el proyecto Visual Studio para generar una implementación de código auxiliar. Y, a continuación, complete la implementación según corresponda. Todos los métodos, propiedades y eventos que defina en IDL son visibles para la aplicación que consume el Windows runtime. Para obtener más información sobre IDL, vea Introducción a Lenguaje de definición de interfaz de Microsoft 3.0.
Para obtener un ejemplo de cómo agregar un evento a su componente Windows runtime, consulte Creación de eventos en C++/WinRT.
Solución de problemas
| Síntoma | Solución |
|---|---|
| En una aplicación de C++/WinRT, al consumir un componente en tiempo de ejecución de Windows de C# que usa XAML, el compilador genera un error con el formato "MyNamespace_XamlTypeInfo": no es miembro de"winrt::MyNamespace",donde MyNamespace es el nombre del espacio de nombres del componente en tiempo de ejecución de Windows. | En pch.h la aplicación C++/WinRT que consume, agregue #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h> , pch.h según corresponda. |