Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Las aplicaciones de escritorio de Windows destinadas a .NET Framework se escriben en un lenguaje de programación determinado y se compilan en lenguaje intermedio (IL). En tiempo de ejecución, un compilador Just-In-Time (JIT) es responsable de compilar el IL en código nativo para la máquina local justo antes de que se ejecute un método por primera vez. En cambio, la cadena de herramientas de .NET Native convierte el código fuente en código nativo en tiempo de compilación. En este artículo se compara .NET Native con otras tecnologías de compilación disponibles para las aplicaciones de .NET Framework y también se proporciona información general práctica sobre cómo .NET Native genera código nativo que puede ayudarle a comprender por qué las excepciones que se producen en el código compilado con .NET Native no se producen en código compilado jiT.
Generación de archivos binarios nativos
Una aplicación que tiene como destino .NET Framework y que no se compila mediante la cadena de herramientas de .NET Native consta del ensamblado de la aplicación, que incluye lo siguiente:
metadatos que describen el ensamblado, sus dependencias, los tipos que contiene y sus miembros. Los metadatos se utilizan para la reflexión y el acceso tardío, y, en algunos casos, también por el compilador y las herramientas de construcción.
Código de implementación. Esto consta de códigos de operación de lenguaje intermedio (IL). En tiempo de ejecución, el compilador Just-In-Time (JIT) lo traduce en código nativo para la plataforma de destino.
Además del ensamblado de aplicación principal, una aplicación requiere que esté presente lo siguiente:
Cualquier biblioteca de clases adicional o ensamblados de terceros que necesite la aplicación. Estos ensamblados incluyen de forma similar metadatos que describen el ensamblado, sus tipos y sus miembros, así como el IL que implementa todos los miembros de tipo.
Biblioteca de clases de .NET Framework. Se trata de una colección de ensamblados instalados en el sistema local con la instalación de .NET Framework. Los ensamblados incluidos en la biblioteca de clases de .NET Framework incluyen un conjunto completo de metadatos y código de implementación.
El tiempo de ejecución común. Se trata de una colección de bibliotecas de vínculos dinámicos que realizan servicios como la carga de ensamblados, la gestión de memoria y la recolección de basura, el manejo de excepciones, la compilación en tiempo de ejecución, la comunicación remota e interoperabilidad. Al igual que la biblioteca de clases, el entorno de ejecución se instala en el sistema local como parte de la instalación de .NET Framework.
Tenga en cuenta que el Common Language Runtime completo, así como los metadatos e IL para todos los tipos en ensamblados específicos de la aplicación, los ensamblados de terceros y los ensamblados del sistema deben estar presentes para que la aplicación se ejecute correctamente.
Compilación Just-In-Time
La entrada para la cadena de herramientas de .NET Native es la aplicación UWP que ha sido compilada por el compilador de C# o Visual Basic. En otras palabras, la cadena de herramientas de .NET Native comienza la ejecución cuando el compilador de lenguaje ha terminado de compilar una aplicación para UWP.
Sugerencia
Dado que la entrada a .NET Native es el IL y los metadatos escritos en ensamblados administrados, todavía puede realizar una generación de código personalizada u otras operaciones personalizadas mediante eventos anteriores o posteriores a la compilación o modificando el archivo de proyecto de MSBuild.
Sin embargo, no se admiten categorías de herramientas que modifican IL y, por tanto, impiden que la cadena de herramientas de .NET analice el IL de una aplicación. Los ofuscadores son las herramientas más importantes de este tipo.
En el transcurso de la conversión de una aplicación de IL a código nativo, la cadena de herramientas de .NET Native realiza operaciones como las siguientes:
Para ciertos caminos de código, reemplaza el código que depende de la reflexión y los metadatos por código nativo estático. Por ejemplo, si un tipo de valor no invalida el método ValueType.Equals, la prueba predeterminada para la igualdad usa la reflexión para recuperar FieldInfo objetos que representan los campos del tipo de valor, compara los valores de campo de dos instancias. Al compilar en código nativo, la cadena de herramientas de .NET Native reemplaza el código de reflexión y los metadatos por una comparación estática de los valores de campo.
Siempre que sea posible, intenta eliminar todos los metadatos.
Incluye en los ensamblados finales de la aplicación solo el código de implementación que realmente invoca la aplicación. Esto afecta especialmente al código en bibliotecas de terceros y en la biblioteca de clases de .NET Framework. Como resultado, una aplicación ya no depende de bibliotecas de terceros ni de la biblioteca de clases completa de .NET Framework; en su lugar, el código de bibliotecas de clases de .NET Framework y de terceros ahora es local para la aplicación.
Reemplaza el CLR completo por un entorno de ejecución refactorizado que contiene principalmente el recolector de elementos no utilizados. El tiempo de ejecución refactorizado se encuentra en una biblioteca denominada mrt100_app.dll que es local para la aplicación y solo tiene un tamaño de unos cientos de kilobytes. Esto es posible porque la vinculación estática elimina la necesidad de muchos de los servicios realizados por Common Language Runtime.
Nota:
.NET Native usa el mismo recolector de elementos no utilizados que Common Language Runtime estándar. En el recolector de elementos no utilizados de .NET Native, la recolección de elementos no utilizados en segundo plano está habilitada de forma predeterminada. Para obtener más información sobre la recolección de elementos no utilizados, vea Aspectos básicos de la recolección de elementos no utilizados.
Importante
.NET Native compila una aplicación completa en una aplicación nativa. No permite compilar un único ensamblado que contenga una biblioteca de clases en código nativo para que se pueda llamar independientemente del código administrado.
La aplicación resultante generada por el conjunto de herramientas de .NET Native se coloca en un directorio llamado ilc.out en el directorio de depuración o publicación del directorio del proyecto. Consta de los siguientes archivos:
<appName>.exe, un ejecutable de código auxiliar que simplemente transfiere el control a una exportación especial de
Main
en <appName>.dll.<appName>.dll, una biblioteca de vínculos dinámicos de Windows que contiene todo el código de la aplicación, así como el código de la biblioteca de clases de .NET Framework y las bibliotecas de terceros en las que tiene una dependencia. También contiene código de compatibilidad, como el código necesario para interoperar con Windows y para serializar objetos en la aplicación.
mrt100_app.dll, un entorno de ejecución refactorizado que proporciona servicios en tiempo de ejecución, como la recolección de elementos no utilizados.
El manifiesto APPX de la aplicación captura todas las dependencias. Además de la aplicación exe, dll y mrt100_app.dll, que se agrupan directamente en el paquete appx, esto incluye dos archivos más:
msvcr140_app.dll, la biblioteca en tiempo de ejecución de C (CRT) usada por mrt100_app.dll. Se incluye mediante una referencia de marco en el paquete.
mrt100.dll. Esta biblioteca incluye funciones que pueden mejorar el rendimiento de mrt100_app.dll, aunque su ausencia no impide que mrt100_app.dll funcione. Se carga desde el directorio system32 en el equipo local, si está presente.
Dado que la cadena de herramientas de .NET Native vincula el código de implementación a la aplicación solo si sabe que la aplicación invoca realmente ese código, es posible que los metadatos o el código de implementación requerido en los escenarios siguientes no se incluyan en la aplicación:
Reflexión.
Invocación dinámica o de resolución tardía.
Serialización y deserialización.
Interoperabilidad COM.
Si los metadatos o el código de implementación necesarios no están presentes en tiempo de ejecución, el entorno de ejecución de .NET Native produce una excepción. Puede evitar estas excepciones y asegurarse de que la cadena de herramientas de .NET Native incluye los metadatos necesarios y el código de implementación, mediante un archivo de directivas en tiempo de ejecución de , un archivo XML que designa los elementos del programa cuyos metadatos o código de implementación deben estar disponibles en tiempo de ejecución y les asigna una directiva en tiempo de ejecución. A continuación se muestra el archivo de directivas de tiempo de ejecución predeterminado que se agrega a un proyecto de UWP compilado por la cadena de herramientas nativas de .NET:
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Assembly Name="*Application*" Dynamic="Required All" />
</Application>
</Directives>
Esto habilita todos los tipos, así como todos sus miembros, en todos los ensamblados de su paquete de aplicación para la reflexión e invocación dinámica. Sin embargo, no habilita la reflexión ni la activación dinámica de tipos en ensamblados de la biblioteca de clases de .NET Framework. En muchos casos, esto es adecuado.