Articulo de referencia

Programación de puentes

En informática , el término "bridging" describe sistemas que mapean el comportamiento en tiempo de ejecución de diferentes lenguajes de programación para que puedan compartir re...

En informática , el término "bridging" describe sistemas que mapean el comportamiento en tiempo de ejecución de diferentes lenguajes de programación para que puedan compartir recursos comunes. Se utilizan a menudo para permitir que lenguajes "externos" operen las bibliotecas de objetos nativas de una plataforma anfitriona , traduciendo datos y estados entre ambos lados del puente. El bridging contrasta con los sistemas de "embedding", que permiten una interacción limitada mediante un mecanismo de caja negra , donde el intercambio de estados es limitado o inexistente.

Apple Inc. ha utilizado ampliamente la interconexión en varias ocasiones, especialmente en las primeras versiones de Mac OS X, que se conectaban con sistemas "clásicos" más antiguos mediante el sistema Carbon y Java . El Common Language Runtime de Microsoft , introducido con .NET Framework , fue diseñado para ser multilingüe desde el principio y evitó la necesidad de soluciones de interconexión complejas. Más recientemente, ambas plataformas han incorporado nuevos sistemas de interconexión para JavaScript : ObjC-to-JS de Apple y HTML Bridge de Microsoft.

Conceptos

Funciones, bibliotecas y entornos de ejecución

La mayoría de los lenguajes de programación incluyen el concepto de subrutina o función, un mecanismo que permite encapsular y reutilizar código de uso común a lo largo de un programa. Por ejemplo, un programa que utiliza intensivamente las matemáticas podría necesitar calcular la raíz cuadrada de varios números. Este código podría aislarse en una sqrt(aNumber)función a la que se le pasa el número sobre el que se calculará la raíz cuadrada y que devuelve el resultado. En muchos casos, el código en cuestión ya existe, ya sea implementado en hardware o como parte del sistema operativo subyacente en el que se ejecuta el programa. En estos casos, la sqrtfunción se puede simplificar aún más llamando al código integrado.

Las funciones suelen agruparse fácilmente en conjuntos de capacidades similares, como funciones matemáticas o de procesamiento de archivos de texto. Generalmente, se agrupan en bibliotecas que se incluyen con el sistema o, más comúnmente en el pasado, con el lenguaje de programación. Cada lenguaje tiene su propio método para llamar a las funciones, por lo que las bibliotecas escritas para un lenguaje pueden no ser compatibles con otro; la semántica para llamar a funciones en C es diferente a la de Pascal , por lo que, en general, los programas en C no pueden llamar a las bibliotecas de Pascal y viceversa. La solución más común a este problema consiste en elegir un conjunto de semántica de llamada como sistema predeterminado para la plataforma y, a continuación, hacer que todos los lenguajes de programación se ajusten a ese estándar.

La mayoría de los lenguajes y plataformas informáticas incorporan funcionalidades que no pueden expresarse mediante el modelo de llamada/retorno de una función. La recolección de basura , por ejemplo, se ejecuta durante toda la vida útil de la aplicación. Este tipo de funcionalidad se encuentra, en efecto, "fuera" del programa; está presente, pero no se expresa directamente en él. Estas funciones suelen implementarse en sistemas de ejecución cada vez más extensos , bibliotecas que se compilan en programas, pero que no necesariamente son visibles dentro del código.

Bibliotecas compartidas y entornos de ejecución comunes

La introducción de los sistemas de bibliotecas compartidas transformó considerablemente el modelo de construcción de programas convencional. Anteriormente, el código de la biblioteca se copiaba directamente en los programas mediante el enlazador y, en la práctica, se integraba al programa. Con el enlace dinámico, el código de la biblioteca (normalmente) reside en un único lugar: un archivo del proveedor del sistema que comparten todas las aplicaciones. Los primeros sistemas presentaban numerosos problemas, a menudo relacionados con el rendimiento, y las bibliotecas compartidas estaban en gran medida aisladas a lenguajes o plataformas específicas, en lugar de integrarse en el sistema operativo en su conjunto. Muchos de estos problemas se resolvieron durante la década de 1990, y a principios de la década de 2000, la mayoría de las plataformas principales habían adoptado las bibliotecas compartidas como interfaz principal para todo el sistema.

Si bien estos sistemas abordaban el problema de proporcionar bibliotecas de código comunes para nuevas aplicaciones, generalmente también añadían sus propios entornos de ejecución. Esto significaba que el lenguaje, la biblioteca y, ahora, todo el sistema, solían estar estrechamente vinculados. Por ejemplo, en OpenStep , todo el sistema operativo era, en efecto, un programa Objective-C . Cualquier programa que se ejecutara en él y deseara utilizar el amplio conjunto de objetos proporcionado por OpenStep no solo tendría que ser capaz de llamar a esas bibliotecas utilizando la semántica de Obj-C, sino también interactuar con el entorno de ejecución de Obj-C para ejercer un control básico sobre la aplicación.

En cambio, el .NET Framework de Microsoft se diseñó desde el principio para admitir varios lenguajes, inicialmente C# , C++ y una nueva versión de Visual Basic . Para ello, Microsoft aisló las bibliotecas de objetos y el entorno de ejecución en la Infraestructura de Lenguaje Común (CLI). En lugar de que los programas se compilen directamente desde el código fuente al formato de entorno de ejecución subyacente, como ocurre en la mayoría de los lenguajes, bajo el modelo CLI todos los lenguajes se compilan primero al Lenguaje Intermedio Común (CIL), que luego llama al Entorno de Ejecución de Lenguaje Común (CLR). En teoría, cualquier lenguaje de programación puede usar el sistema CLI y los objetos .NET.

Puentes

Si bien plataformas como macOS y .NET permiten adaptar la mayoría de los lenguajes de programación a su entorno de ejecución, también es cierto que estos lenguajes suelen tener un entorno de ejecución específico en mente: Objective-C requiere esencialmente el entorno de ejecución de Objective-C, mientras que C# requiere el CLR. Si se desea utilizar código C# dentro de Objective-C, o viceversa, es necesario encontrar una versión compatible con el otro entorno de ejecución, la cual a menudo no existe.

Una versión más común de este problema se refiere al uso de lenguajes independientes de la plataforma, como Java, que cuentan con sus propios entornos de ejecución y bibliotecas. Si bien es posible crear un compilador de Java que llame al sistema subyacente, como J#, dicho sistema no podría interactuar con otro código Java a menos que también se recompilara. El acceso al código en las bibliotecas de Java puede resultar difícil o imposible.

El auge del navegador web como una especie de sistema operativo virtual ha agudizado este problema. El paradigma de programación moderno bajo HTML5 incluye el lenguaje JavaScript (JS), el Modelo de Objetos del Documento ( DOM ) como biblioteca principal y el propio navegador como entorno de ejecución. Si bien sería posible crear una versión de JS que se ejecute en el CLR, esto desvirtuaría en gran medida el propósito de un lenguaje diseñado principalmente para operar navegadores; a menos que el compilador pueda interactuar directamente con el navegador, su uso carece de sentido.

En estos casos, y en muchos otros similares, surge la necesidad de un sistema que permita la interoperabilidad de los dos entornos de ejecución. Esto se conoce como "conectar" los entornos de ejecución.

Ejemplos

Manzana

Apple ha hecho un uso considerable de tecnologías puente desde los primeros esfuerzos que llevaron a Mac OS X.

Cuando Apple adquirió NeXT, el plan era crear una nueva versión de OpenStep, entonces conocida como Rhapsody , con un emulador llamado Blue Box que ejecutaría programas clásicos de Mac OS. Esto generó una fuerte oposición por parte de la comunidad de desarrolladores, y Rhapsody fue cancelado. [ 1 ] En su lugar, OS X implementaría muchas de las funciones antiguas de Mac OS sobre la funcionalidad principal de OpenStep, facilitando así la migración de las aplicaciones existentes.

Para ello, Apple tomó código útil de la plataforma OpenStep y reimplementó la funcionalidad principal en una biblioteca C pura conocida como Core Foundation , o CF para abreviar. Las bibliotecas de OpenStep que llamaban al código subyacente de CF se convirtieron en la API Cocoa , mientras que las nuevas bibliotecas C similares a las de Mac se convirtieron en la API Carbon . Dado que los lados C y Obj-C del sistema necesitaban compartir datos, y los datos en el lado Obj-C normalmente se almacenaban en objetos (en lugar de tipos base), las conversiones hacia y desde CF podían ser costosas. Apple no estaba dispuesta a pagar esta penalización de rendimiento, por lo que implementó un esquema conocido como "puente gratuito" para ayudar a reducir o eliminar este problema. [ 2 ]

En ese momento, Java se estaba convirtiendo en un actor importante en el mundo de la programación, y Apple también proporcionó una solución de puenteo de Java que se desarrolló para la plataforma WebObjects . Esta era una solución de puenteo más clásica, con conversiones directas entre Java y tipos OpenStep/CF que se completaban en el código, cuando era necesario. Bajo Carbon, un programa que usaba CFStrings usaba el mismo código que una aplicación Cocoa que usaba NSString, y ambos podían conectarse sin problemas. Con el puenteo de Java, los CFStrings se convertían en objetos String propios de Java, lo que requería más trabajo pero hacía que la portabilidad fuera prácticamente invisible. [ 3 ] Otros desarrolladores hicieron un uso generalizado de tecnologías similares para brindar soporte para otros lenguajes, incluido el sistema de "peering" utilizado para permitir que el código Obj-C llamara al código .NET bajo Mono . [ 4 ]

A medida que disminuía la necesidad de estas soluciones de portabilidad, tanto Carbon como Java Bridge fueron descontinuados y finalmente eliminados de versiones posteriores del sistema. [ 5 ] [ 6 ] La compatibilidad con Java se migró al uso de la Interfaz Nativa de Java (JNI), un estándar del mundo Java que permitía que Java interactuara con código basado en C. En OSX, la JNI permitía usar código Obj-C, aunque con cierta dificultad. [ 7 ]

Hacia 2012, el extenso trabajo de Apple en WebKit dio lugar a la introducción de una nueva tecnología de puente que permite que el código de programación JavaScript llame al entorno de ejecución Obj-C/Cocoa, y viceversa. Esto permite la automatización del navegador mediante Obj-C o, alternativamente, la automatización de aplicaciones Cocoa mediante JavaScript. Originalmente parte del navegador web Safari , en 2013 el código se integró en el nuevo OSX 10.9. [ 8 ]

Microsoft

Aunque en el pasado se han utilizado algunos ejemplos de puenteo, el sistema CLI de Microsoft se diseñó para admitir lenguajes sobre el sistema .NET en lugar de ejecutarse bajo entornos de ejecución nativos y puenteos. Esto dio lugar a la implementación de varios lenguajes nuevos en el sistema CLI, que a menudo incluían el símbolo de almohadilla (#) o la palabra "Iron" en su nombre. Consulte la Lista de lenguajes CLI para obtener un conjunto más completo de ejemplos. Este concepto se interpretó como un ejemplo de la estrategia de Microsoft de adoptar, extender y extinguir , ya que produjo lenguajes similares a Java (como C# y J# ) que no eran compatibles entre sí ni utilizaban sus bibliotecas.

No obstante, el ecosistema clásico de Windows incluía una cantidad considerable de código que debía utilizarse en el entorno .NET, y para ello Microsoft introdujo un sistema de interconexión con un buen soporte. Este sistema incluía numerosas utilidades y características de lenguaje para facilitar el uso de código de Windows o Visual Basic dentro del sistema .NET, [ 9 ] o viceversa. [ 10 ]

Microsoft también ha introducido una tecnología de puenteo de JavaScript para Silverlight , el HTML Bridge. El Bridge expone los tipos de JS al código .NET, los tipos de .NET al código JS y gestiona la seguridad de memoria y acceso entre ellos. [ 11 ] [ 12 ]

Otros ejemplos

Tecnologías de puenteo similares, a menudo con JavaScript en un lado, son comunes en varias plataformas. Un ejemplo es el puente JS para el sistema operativo Android escrito a modo de ejemplo. [ 13 ]

El término también se utiliza a veces para describir los sistemas de mapeo objeto-relacional , que sirven de puente entre el mundo de las bases de datos SQL y los lenguajes de programación orientados a objetos modernos.

Referencias

  1. Dave Winer, "Rhapsody Cancelled" , 12 de mayo de 1998
  2. "Tipos puenteados de números gratuitos" , Apple, 19 de septiembre de 2012
  3. "Uso del puente Java" , Apple
  4. "Puenteando"
  5. Andrew Youll, "Apple abandona el puente entre Cocoa y Java" , OSNews, 10 de julio de 2005
  6. "Descontinuación de Carbon Core" , Apple, 23 de julio de 2013
  7. "Nota técnica TN2147: Desarrollo de JNI en Mac OS X" , Apple, 14 de julio de 2011
  8. Nigel Brooke, "El nuevo puente de Apple entre Objective-C y JavaScript" , 14 de mayo de 2013
  9. Jason Clark, "Llamando a un método administrado de .NET desde código nativo" , Revista MSDN
  10. "Llamar a un método administrado de .NET desde código nativo" , Microsoft
  11. "HTML Bridge: Interacción entre HTML y código administrado" , Microsoft
  12. "Uso del puente HTML" , Microsoft
  13. "Desarrollo de Android: Ejemplo de puente JavaScript – ¡Explicación completa!" Archivado el 29 de julio de 2013 en Wayback Machine , object graph, 16 de mayo de 2012