Articulo de referencia

Extensiones administradas para C++

Las extensiones administradas para C++ o Managed C++ son un conjunto obsoleto de extensiones de lenguaje para C++ , que incluyen extensiones gramaticales y sintácticas, palabras...

Las extensiones administradas para C++ o Managed C++ son un conjunto obsoleto de extensiones de lenguaje para C++ , que incluyen extensiones gramaticales y sintácticas, palabras clave y atributos, para llevar la sintaxis y el lenguaje C++ al .NET Framework . Estas extensiones fueron creadas por Microsoft para permitir que el código C++ se ejecute en Common Language Runtime (CLR) como código administrado , y que continúe interactuando con el código nativo.

En 2004, las extensiones de Managed C++ se revisaron significativamente para clarificar y simplificar la sintaxis y ampliar la funcionalidad para incluir genéricos administrados . Estas nuevas extensiones se denominaron C++/CLI y se incluyeron en Microsoft Visual Studio 2005. [ 1 ] Por lo tanto, el término Managed C++ y las extensiones a las que se refiere están obsoletos y han sido reemplazados por las nuevas extensiones.

Historia

Microsoft introdujo las Extensiones Administradas para C++ en Microsoft Visual C++ 2002 (MSVC++). Microsoft intentó minimizar las diferencias entre el C++ estándar y las Extensiones Administradas para C++, lo que provocó que las diferencias fundamentales entre ambos quedaran sintácticamente ocultas. MSVC++ 2003 y 2005 también ofrecieron soporte para escribir programas en C++ administrado. En 2004, las Extensiones Administradas para C++ quedaron obsoletas en favor de C++/CLI , un segundo intento de Microsoft por admitir la programación para la Infraestructura de Lenguaje Común utilizando C++. [ 2 ]

Diseño

El término "administrado" se refiere al código administrado que se ejecuta en la máquina virtual .NET , la cual funciona como un entorno aislado para una mayor seguridad mediante comprobaciones en tiempo de ejecución, como la detección de desbordamientos de búfer. Además, las aplicaciones escritas en C++ administrado se compilan a CIL (Lenguaje Intermedio Común) y no directamente a instrucciones nativas de la CPU, como ocurre con las aplicaciones C++ estándar.

El código C++ administrado puede interactuar con cualquier otro lenguaje también compatible con CLR , como C# y Visual Basic .NET , y aprovechar las características que ofrece CLR , como la recolección de basura . Esto significa que C++ administrado ocupa una posición única en el conjunto de lenguajes .NET. Es el único lenguaje que puede comunicarse directamente con lenguajes .NET (como C# y VB.NET), así como con C++ nativo. Los demás lenguajes .NET solo pueden comunicarse con código C++ mediante PInvoke o COM . Sin embargo, dado que C++ administrado puede comunicarse directamente tanto en contextos de C++ administrado como estándar, se utiliza a menudo como un puente.

Funcionalidad

Los programas escritos en Managed C++ ofrecen funcionalidades adicionales del .NET Framework y del CLR . La más destacada es la recolección de basura , que libera al programador de la gestión manual de la memoria. El recolector de basura (GC) es gestionado por el CLR. La gestión de la memoria se ejecuta con bastante rapidez, pero para aplicaciones que requieren un rendimiento óptimo, el código nativo no administrado suele ser la opción preferida.

C++ administrado está orientado a la programación orientada a objetos. Una diferencia importante entre C++ estándar y C++ administrado es que no admite la herencia múltiple , y una clase administrada por el recolector de basura de CLR no puede heredar de más de una clase. Esto se debe a una limitación de CLR.

Características principales:

  • Metadatos extensibles: información que describe la estructura y los tipos de un componente administrado. Se pueden extender y reutilizar para crear componentes de software. Se utilizan ampliamente en C# y Visual Basic .NET.
  • Recogida de basura: el CLR está totalmente gestionado por un recolector de basura para la gestión de memoria, automatizada por el propio CLR; es decir, no es necesario llamar al operador delete en el código C++ gestionado.
  • Interoperabilidad con lenguajes .NET: el código destinado al .NET Framework produce una salida en Microsoft Intermediate Language (MSIL, similar al bytecode de Java) y, por lo tanto, los módulos compilados y los componentes (más bien ensamblados) pueden ser reutilizados por otros componentes de programas escritos en otro lenguaje destinado al .NET Framework, como JScript .NET, C#, Visual Basic .NET y otros lenguajes de terceros para .NET.
  • Control de versiones: se pueden introducir nuevos métodos y miembros de datos en las clases gestionadas existentes sin romper la compatibilidad binaria con el software del lado del cliente existente.
  • Encabezados binarios: permiten reutilizar metadatos precompilados; cualquier archivo .exe, .dll, .obj o .netmodule compilado en MSIL puede referenciarse desde un archivo fuente de C++.
  • Protección contra desbordamiento de búfer: gracias a la introducción de la recolección de basura en C++, C++ administrado es menos propenso a los errores comunes de desbordamiento de búfer causados ​​por la ausencia de verificación de tipos de datos en C++ estándar. El recolector de basura ayuda a reducir (aunque no por completo) la frecuencia de estos errores.
  • Biblioteca de clases base de .NET Framework : C++ administrado también tiene el potencial de ser menos verboso que el código estándar no administrado, ya que todas las llamadas a funciones administradas y las clases heredadas se derivan de la Biblioteca de clases base de .NET Framework (BCL, a veces denominada FCL o Biblioteca de clases de Framework), cuya API proporciona capacidades de red TCP/IP, funciones de manipulación de texto, acceso a datos (desde ODBC hasta SQL), servicios XML (desde XSD hasta XSL), programación de GUI (Windows Forms), servicios de correo (SMTP), criptografía (certificados X509 y firmas digitales XML), generación de MSIL (esencialmente, emisión de instrucciones en MSIL), E/S de archivos, manipulación manual del recolector de basura CLR e información de administración para manipular la consola WMI.

Ventajas sobre el código nativo

  • El código administrado y el no administrado pueden combinarse sin problemas en el mismo ensamblado de la CLI . Esto permite al programador conservar el código no administrado que no se puede migrar a .NET Framework sin tener que reescribirlo por completo. Sin embargo, el uso de esta convención híbrida conlleva algunas consecuencias.
  • C++ administrado es el único lenguaje que puede contener código no administrado y comunicarse de forma nativa con todos los demás lenguajes .NET. Por lo tanto, C++ administrado resulta muy conveniente para la interoperabilidad entre programadores que utilizan diferentes lenguajes, incluidos aquellos del entorno .NET y aquellos que utilizan C++ estándar.

Desventajas en comparación con el código no administrado

  • Managed C++ introduce muchas palabras clave y convenciones sintácticas nuevas que pueden perjudicar la legibilidad del código, especialmente si el código C++ se incluye directamente e interactúa directamente con el código Managed C++ en el mismo ensamblado.
  • El C++ administrado ha sido reemplazado por C++/CLI y, por lo tanto, está obsoleto, ya que C++/CLI ha sido estandarizado.

Desventajas en comparación con el código totalmente administrado

  • El C++ administrado requiere un tiempo de desarrollo ligeramente mayor que otros lenguajes .NET que podrían aplicarse a proyectos que produzcan los mismos resultados. El uso de punteros puede ser o no un requisito, ya que el C++ administrado cuenta con tipos de valor (estructura __value y clase __value) y tipos de referencia (estructura __gc y clase __gc).
  • Managed C++ es totalmente compatible con las aplicaciones web ASP.NET , aunque el desarrollo es más difícil que con otros lenguajes .NET, incluidos algunos lenguajes de terceros.
  • C++ administrado solo admite plantillas (para la interoperabilidad con C++ nativo), pero no admite genéricos (para la interoperabilidad con todos los demás lenguajes .NET). C++/CLI admite tanto plantillas (en tiempo de compilación) como genéricos (en tiempo de ejecución).

Ejemplos

Los siguientes ejemplos ilustran el uso de C++ administrado en comparación con C++ estándar:

  • (Cambio global) El código C++ existente que se vaya a portar a través de CLR debe ir acompañado de lo siguiente:
// Gello.cpp// nueva directiva using #using <mscorlib.dll>// otra directiva using namespace. using namespace System ;int main () { Console :: WriteLine ( "Hola, mundo!" ); return 0 ; }

Una nueva directiva de preprocesador

#usando <mscorlib.dll>

es necesario. Además de eso, se requieren más directivas #using para importar más bibliotecas para usar más espacios de nombres en la Biblioteca de Clases Base, como

#usando <System.Windows.Forms.dll>

y

using namespace System :: Windows :: Forms ;

para usar Formularios de Windows.

  • Para compilar código que tenga como destino el CLR, es necesario introducir una nueva opción de compilador.
 cl.exe hello.cpp /clr

/clr permite que cualquier código que haga referencia a .NET Framework se compile como CIL .

  • Se puede designar una clase para que sea recolectada como basura mediante la __gcpalabra clave de extensión.
// GarbageCollected.cpp#usando <mscorlib.dll>__gc clase GarbageCollected { int * i ; char * g ; float * j ; };int main () { while ( true ) { GarbageCollected ^ _gc = gcnew GarbageCollected (); } return 0 ; }

El código anterior se puede compilar y ejecutar sin temor a fugas de memoria . Dado que la clase gces administrada por el recolector de basura, no es necesario llamar al deleteoperador. Para lograr lo mismo con código no administrado, deletese requiere la palabra clave:

// NotGarbageCollected.cppclase NotGarbageCollected { int * i ; char * g ; float * j ; };int main () { while ( true ) { NotGarbageCollected * g = new NotGarbageCollected (); delete g ; } return 0 ; }

Notas:

  • Una clase designada con __gc puede tener un constructor declarado.
  • Una clase designada con __gc puede tener un destructor declarado.
  • Una clase designada con __gc no puede heredar de más de una clase. (Esta es una limitación del CLR).
  • Una clase designada con __gc no puede heredar de otra clase que no esté designada con __gc.
  • Una clase designada con __gc no puede ser heredada por otra clase que no esté designada con __gc.
  • Una clase designada como __gc puede implementar cualquier número de interfaces __gc.
  • Una clase designada como __gc no puede implementar una interfaz no administrada.
  • Una clase designada con __gc no se hace visible fuera de su propio ensamblado por defecto.
public __gc class MyClass { // ... };

la palabra clave pública para modificar el acceso de una clase designada con __gc.

Una clase designada con __gc puede destruirse manualmente utilizando la palabra clave delete, pero solo si la clase designada con __gc tiene un destructor definido por el usuario.

  • Se puede declarar una interfaz anteponiéndole la palabra clave de extensión __gc. Por ejemplo:
// MyInterface.cpp #usando <mscorlib.dll>__gc __interface MyInterface { void init (); int common (); }

El código anterior debe compilarse con /clr y /LD para producir un archivo DLL simple.

Notas:

  • Una interfaz __gc no puede contener miembros de datos, miembros estáticos, declaraciones de clases anidadas ni especificadores de acceso.
  • Una interfaz __gc solo puede heredar de otra interfaz __gc o de System::Object. La herencia de System::Object es el comportamiento predeterminado.
  • Una interfaz __gc no puede contener ninguna implementación (código base) de los prototipos de función declarados.

Comparación con otros idiomas

A continuación se exponen los puntos principales y los estándares de programación que diferencian a Managed C++ de otros lenguajes de programación conocidos que son similares en concepto.

C++ estándar

Desventajas

  • El código C++ nativo puede ser más rápido en tiempo de ejecución.
  • C++ no requiere la instalación de un compilador asociado ni de un entorno de ejecución gestionado en el sistema de destino.
  • C++ admite la programación genérica . Sin embargo, hasta la versión final de C++/CLI, los programadores de Managed C++ deben recurrir a soluciones alternativas para usar genéricos.
  • C++ admite la palabra clave "const" y la corrección de constantes . C++ administrado, como Java y C#, no incluye esta característica. Una alternativa es hacer que una clase administrada sea inmutable o restringir los accesores de tipo en las interfaces públicas.
  • El código C++ no está sujeto a las restricciones del CLR. Por ejemplo, el CLR no permite que las clases hereden de otras clases de forma privada ni protegida, por lo que lo siguiente producirá un error de compilación:
public __gc class First { int i ; };public __gc class Second : private First { int h ; i = h ; }; // errorpublic __gc class Third : protected First { int h ; i = h ; }; // error
  • Las clases __gc de C++ administradas no pueden heredar de más de una clase, por lo que lo siguiente producirá un error de compilación:
__gc class First {}; __gc class Second {}; __gc class Third : public First , public Second {}; // producirá un error

Ventajas

  • El C++ administrado admite un mayor grado de reflexión que el C++ estándar, lo cual suele ser mucho más conveniente dependiendo de la función del código o del propósito del mismo.
  • El C++ administrado puede interoperar con todos los demás lenguajes compatibles con .NET, incluidos otros lenguajes de terceros.
  • En C++ administrado, la memoria se gestiona mediante recolección de basura. En C++ estándar, la gestión y asignación de memoria es responsabilidad del programador.

Java

Diferencias

  • Para ejecutar código Java se requiere una máquina virtual adecuada, mientras que para ejecutar código C++ administrado se requiere una implementación adecuada del .NET Framework.

Desventajas

  • Java proporciona documentación sobre el código fuente, mientras que Managed C++ no.
  • Java cuenta con muchas otras herramientas de desarrollo disponibles para los programadores de Java, mientras que Managed C++ solo está disponible en Visual Studio .NET .

Ventajas

  • El C++ administrado puede acceder al sistema informático a través de una interfaz de bajo nivel con mucha más facilidad que Java. Los programadores de Java deben usar JNI (Java Native Interface) para utilizar los servicios de bajo nivel del sistema operativo anfitrión.

DO#

Diferencias

  • Si bien C# admite punteros al igual que C++, esta función está desactivada por defecto.

Desventajas

  • Al igual que Java , C# es sintácticamente más sencillo al trabajar con código administrado.
  • C# puede lograr básicamente el mismo resultado que Managed C++, ya que todas las convenciones sintácticas y estructurales siguen siendo sorprendentemente similares.
  • Aunque C++ administrado es un lenguaje fuertemente tipado debido a su introducción en el CLR, puede ser propenso a errores si se introduce código compilado no administrado en la misma base de código, mientras que C# es MSIL puro.

Ventajas

  • C# debe utilizar el .NET Framework y las bibliotecas de clases proporcionadas para acceder al sistema informático a un nivel bajo.
  • Migrar aplicaciones de C o C++ a .NET Framework es mucho más sencillo con Managed C++.
  • El compilador Microsoft Visual C++ .NET, que compila Managed C++ para que tenga como destino el .NET Framework, produce un conjunto de instrucciones mucho más maduro en su código ensamblador resultante, lo que mejora el rendimiento.

Véase también

Referencias

  1. "Guía de traducción: Cómo trasladar sus programas de Managed Extensions for C++ a C++/CLI" . Microsoft . Agosto de 2004. Consultado el 11 de noviembre de 2009 .
  2. Sutter, Herb. "Una justificación de diseño para C/C++" (PDF) . pág. 6. Archivado (PDF) del original el 30 de agosto de 2017. Recuperado el 12 de junio de 2018 . 
  • Extensiones administradas para C++ (en MSDN)
  • Artículo: C++ / CLI – ¿Cómo usar las DLL de C++ administrado cuando no está instalado Microsoft Visual C++ Redistributable?