- Biblioteca (informática)
-
Biblioteca (informática)
En ciencias de la computación, una biblioteca (o librería) es un conjunto de subprogramas utilizados para desarrollar software. Las bibliotecas contienen código y datos, que proporcionan servicios a programas independientes, es decir, pasan a formar parte de éstos. Esto permite que el código y los datos se compartan y puedan modificarse de forma modular. Algunos programas ejecutables pueden ser a la vez programas independientes y bibliotecas, pero la mayoría de éstas no son ejecutables. Ejecutables y bibliotecas hacen referencias (llamadas enlaces) entre sí a través de un proceso conocido como enlace, que por lo general es realizado por un software denominado enlazador.
La mayoría de los sistemas operativos modernos proporcionan bibliotecas que implementan la mayoría de los servicios del sistema. De esta manera, estos servicios se convierten en una "materia prima" que cualquier aplicación moderna espera que el sistema operativo ofrezca. Como tal, la mayor parte del código utilizado por las aplicaciones modernas se ofrece en estas bibliotecas.
Contenido
Nota terminológica
Habitualmente se emplea el término librería para referirse a una biblioteca, por la similitud con el original inglés library. Ambos términos, biblioteca y librería, son correctos según las definiciones (biblioteca,[1] librería[2] ) de la RAE, aunque en términos formales, la acepción correcta es biblioteca, porque es la traducción correcta de library, mientras que el término inglés para librería es book shop (literalmente: tienda de libros), o bien bookshelf (estantería o mueble para guardar libros, librería). También es habitual referirse a ella con el término de origen anglosajón toolkit (conjunto, equipo, maletín, caja, estuche, juego (kit) de herramientas).
Así, a pesar de que el término librería se haya difundido en ámbitos informales, no es estrictamente correcto.
Historia
Los primeros conceptos de programación similares a las bibliotecas intentaban separar las definiciones de datos de la implementación del programa. El concepto COMPOOL (Communication Pool) fue popularizado por JOVIAL en 1959, aunque tomó la idea prestada del software de los grandes sistemas SAGE. Siguiendo los principios de las ciencias de la computación de "separación de problemas" (aislar problemas pequeños fáciles de abordar) y "ocultación de información", "el propósito del COMPOOL es permitir el intercambio de datos del sistema entre varios programas, proporcionando una descripción centralizada de los mismos" (Wexelblat 1981:369).
COBOL incluyó un "primitivo sistema de bibliotecas" en el año 1959 (Wexelblat 1981:274), pero Jean Sammet las describió retrospectivamente como "recursos insuficientes de biblioteca" (Wexelblat 1981:258).
Otra de las grandes contribuciones al concepto moderno de biblioteca fue la innovación de subprograma de FORTRAN. Éstos pueden ser compilados con independencia unos de otros, pero el compilador carece de un enlazador, por lo que el chequeo de tipos entre los subprogramas resulta imposible (Wilson et. Al. 1988:126).
Por último, se debe hablar de la influencia que Simula 67 tuvo en el concepto de 'biblioteca'. Simula es el primer lenguaje de programación orientado a objetos, y sus clases son casi idénticas que el concepto actual que se utiliza en Java, C++ y C#. El concepto de clase de Simula fue también el origen del "paquete" en Ada y el "módulo" de Modula-2 (Wilson et. Al. 1988:52). A pesar de haber sido desarrollado en 1965, las clases de Simula podían ser incluidas en ficheros de biblioteca y añadidas en tiempo de compilación (Wexelblat 1981:716).
Tipos
Bibliotecas estáticas
Históricamente, las bibliotecas sólo podían ser estáticas. Una biblioteca estática, también conocido como archivo, consiste en un conjunto de rutinas que se copian en una aplicación por el compilador o el enlazador, produciendo archivos con código objeto y un fichero ejecutable independiente. Este proceso, y el archivo ejecutable, se conoce como una construcción estática de la aplicación objetivo. La dirección real, las referencias para saltos y otras llamadas a rutinas se almacenan en una dirección relativa o simbólica, que no puede resolverse hasta que todo el código y las bibliotecas son asignadas a direcciones estáticas finales.
El enlazador resuelve todas las direcciones no resueltas convirtiéndolas en direcciones fijas o relocalizables (desde una base común) cargando todo el código y las bibliotecas en posiciones de memoria en tiempo de ejecución. Este proceso de enlazado puede durar incluso más tiempo que el proceso de compilación, y debe ser realizado cada vez que alguno de los módulos es recompilado. La mayoría de los lenguajes compilados tienen biblioteca estándar (por ejemplo, la biblioteca estándar de C), pero los programadores también pueden crear sus propias bibliotecas personalizadas. Los compiladores comerciales proporcionan tanto las bibliotecas estándar como las personalizadas.
Un enlazador pueden trabajar sobre tipos específicos de ficheros objeto, y por lo tanto requiere tipos específicos (compatibles) de bibliotecas. Los ficheros objeto recopilados en una biblioteca pueden distribuirse y utilizarse fácilmente. Un cliente, ya sea un programa o una biblioteca de subrutinas, accede a una biblioteca objeto referenciando sólo por su nombre. El proceso de enlazado resuelve las referencias buscando en las bibliotecas del orden dado. Por lo general, no se considera un error si un nombre puede encontrarse varias veces en un determinado conjunto de las bibliotecas.
Bibliotecas dinámicas
Enlace dinámico significa que las subrutinas de una biblioteca son cargadas en un programa en tiempo de ejecución, en lugar de ser enlazadas en tiempo de compilación, y se mantienen como archivos independientes separados del fichero ejecutable del programa principal. El enlazador realiza una mínima cantidad de trabajo en tiempo de compilación, registra que rutinas de la biblioteca necesita el programa y el índice de nombres o números de las rutinas en la biblioteca. La mayor parte de la labor de enlazado se realiza en el momento en que la aplicación se carga (tiempo de carga o loadtime) o durante la ejecución (tiempo de ejecución o runtime). El necesario código enlazado, llamado por el cargador, es de hecho parte del sistema operativo subyacente. En el momento adecuado el cargador localiza las bibliotecas en el disco y añade los datos relevantes de éstas en el espacio de memoria del proceso.
Algunos sistemas operativos sólo pueden enlazar una biblioteca en tiempo de carga, antes de que el proceso comience su ejecución, otros son capaces de esperar hasta después de que el proceso haya empezado a ejecutarse y enlazar la biblioteca sólo cuando efectivamente se hace referencia a ella (es decir, en tiempo de ejecución). Esto último se denomina "retraso de carga". En cualquier caso, esa biblioteca es una biblioteca enlazada dinámicamente.
El enlace dinámico, por su naturaleza, tiene tan sólo las limitaciones establecidas por las licencias de software.
Los plugins son un uso común de las bibliotecas enlazadas dinámicamente, que son especialmente útiles cuando unas bibliotecas pueden ser sustituidas por otras con una interfaz similar, pero diferente funcionalidad. Se puede decir que un software tiene una "arquitectura de plugin" si utiliza bibliotecas con una funcionalidad básica con la intención de que puedan ser sustituidas. Sin embargo, el uso de las bibliotecas enlazadas dinámicamente en la arquitectura de una aplicación no significa necesariamente que puedan ser sustituidas.
El enlace dinámico se desarrolló originalmente en los sistemas operativos Multics a partir de 1964. Se trataba de una característica del MTS (Michigan Terminal System), construido a finales de los 60.[3] En Microsoft Windows, las bibliotecas enlazadas dinámicamente se denominan DLL (dynamic-link library).
Relocalización
Uno de los problemas que el cargador debe gestionar es que la localización real de los datos de la biblioteca no puede conocerse hasta que el ejecutable y todas las bibliotecas dinámicas que se han enlazado han sido cargadas en memoria. Eso es debido a que las localizaciones en memoria dependen de qué bibliotecas dinámicas se han cargado. No es posible depender de la dirección absoluta de los datos en el ejecutable, ni incluso en la biblioteca, ya que podrían producirse conflictos entre las diferentes bibliotecas: si dos de ellas utilizaran las mismas direcciones o sus direcciones se solaparan, sería imposible utilizar ambas en el mismo programa.
Sin embargo, en la práctica, en muchos de los sistemas las bibliotecas no cambian frecuentemente. Por tanto, es posible calcular una dirección de carga probable para cada biblioteca compartida en el sistema antes de que sea utilizada, y almacenar esa información en bibliotecas y ejecutables. Si cada biblioteca que es cargada es tratada así, entonces cada una de ellas será cargada en direcciones predeterminadas, lo que acelera el proceso de enlace dinámico. Esta optimización se conoce como Prebinding en Mac OS X y Prelinking en Linux. Las desventajas de esta técnica son el tiempo requerido de precálculo de las direcciones cada vez que las bibliotecas compartidas cambian, la incapacidad de usar técnicas como la aleatorización de los espacios de direcciones, y el consumo de espacio virtual de direcciones (un problema que queda mitigado por el uso de arquitecturas de 64 bits, al menos en la actualidad).
Un antiguo método era examinar el programa en tiempo de carga. Una vez que todas las bibliotecas fueran cargadas, se reemplazan todas las referencias a datos en las bibliotecas, con punteros a localidades de memoria apropiados. En Windows 3.1 (y algunos sistemas embebidos como las calculadoras Texas Instruments), las referencias eran manejadas como listas ligadas, permitiendo la fácil enumeración y reemplazo. Ahora, la mayoría de las bibliotecas dinámicas ligan una tabla de símbolos con direcciones en blanco dentro del programa en tiempo de compilación. Todas las referencias a código o datos en la biblioteca pasan a través de esta tabla. En tiempo de carga, la tabla es modificada con la dirección de los datos/código por el linker. Este proceso es lento y afecta significativamente la velocidad de los programas que llaman continuamente a otros programas, tal como algunos scripts de shell.
La biblioteca contiene una tabla de saltos de todos los métodos que contiene, denominados puntos de entrada. Las llamadas dentro de la biblioteca "saltan a lo largo" de la tabla, buscando la ubicación del código en memoria, y a continuación solicitándolo. Estas solicitudes suponen un sobreesfuerzo, pero el retardo es habitualmente tan pequeño que es despreciable.
Localización de bibliotecas en tiempo de ejecución
Los enlazadores/cargadores dinámicos tienen una funcionalidad muy amplia. Algunos dependen de rutas explícitas a las bibliotecas almacenadas en los ejecutables. Cualquier cambio en la nomenclatura o el diseño del sistema de ficheros hará que estos sistemas fallen. Habitualmente sólo se almacena en el ejecutable el nombre de la biblioteca (no la ruta), siendo el sistema operativo el que proporciona el mecanismo para encontrar la biblioteca en el disco mediante ciertos algoritmos.
Una de las mayores desventajas del enlace dinámico es que el funcionamiento correcto de los ejecutables depende de una serie de bibliotecas almacenadas de forma aislada. Si la biblioteca es borrada, movida o renombrada, o si una versión incompatible de DLL es copiada en una ubicación que aparece antes en la ruta de búsqueda, el ejecutable no se podrá cargar. En Windows esto se conoce como DLL hell (en español Infierno de DLL).
Sistemas Unix
La mayor parte de los sistemas tipo Unix disponen de una "ruta de búsqueda" que especifica los directorios del sistema de archivos en los que buscar las bibliotecas dinámicas. En algunos sistemas, la ruta por defecto es especificada en un archivo de configuración; en otros, está codificada a fuego (hard coded) en el cargador dinámico. Algunos formatos de fichero ejecutable pueden especificar directorios adicionales en los que buscar las bibliotecas de un determinado programa. Esto puede ser usualmente alterado por una variable de entorno, aunque es deshabilitado para programas que tengan setuid o setgid, de manera que el usuario no puede forzar a ese programa a ejecutar un código arbitrario. Es aconsejable que los desarrolladores de bibliotecas pongan sus bibliotecas dinámicas en directorios que se encuentren en la ruta de búsqueda por defecto. Por el contrario, esto puede hacer problemática la instalación de nuevas bibliotecas, pues hace que esos directorios crezcan mucho haciéndose complicada su gestión.
Carga dinámica
Bibliotecas remotas
Otra solución al problema de las bibliotecas es usar ejecutables completamente separados (often in some lightweight form) y llamarlos usando una llamada de procedencia and call them using a remote procedure call (RPC) sobre la red a otra computadora
Bibliotecas compartidas
Bibliotecas objeto
Referencias
- ↑ RAE. «Definición de biblioteca».
- ↑ RAE. «Definición de librería».
- ↑ «A History of MTS» Information Technology Digest. Vol. 5. n.º 5.
Véase también
Categoría: Bibliotecas de programación
Wikimedia foundation. 2010.