En informática , una biblioteca es una colección de recursos de solo lectura que se aprovecha durante el desarrollo de software para implementar un programa de computadora .
Históricamente, una biblioteca constaba de subrutinas (hoy generalmente llamadas funciones). El concepto ahora incluye otras formas de código ejecutable , incluidas clases y datos no ejecutables, incluidas imágenes y texto . También puede referirse a una colección de código fuente .
Por ejemplo, un programa podría usar una biblioteca para realizar llamadas al sistema indirectamente en lugar de realizarlas directamente en el programa.
Una biblioteca puede ser utilizada por múltiples consumidores independientes (programas y otras bibliotecas). Esto difiere de los recursos definidos en un programa que generalmente solo pueden ser utilizados por ese programa.
Cuando un consumidor utiliza un recurso de la biblioteca, obtiene el valor de la biblioteca sin tener que implementarlo él mismo. Las bibliotecas fomentan la reutilización de código de forma modular .
Al escribir código que utiliza una biblioteca, un programador sólo necesita conocer información de alto nivel, como qué elementos contiene y cómo utilizarlos, no todos los detalles internos de la biblioteca.
Las bibliotecas pueden utilizar otras bibliotecas, lo que da como resultado una jerarquía de bibliotecas en un programa.
Una biblioteca de código ejecutable tiene una interfaz bien definida mediante la cual se invoca la funcionalidad. Por ejemplo, en C , se invoca una función de biblioteca a través de la capacidad de llamada de función normal de C. El vinculador genera código para llamar a una función a través del mecanismo de la biblioteca si la función está disponible en una biblioteca en lugar de desde el programa mismo. [1]
Las funciones de una biblioteca se pueden conectar al programa que las invoca en diferentes fases del ciclo de vida del programa . Si se accede al código de la biblioteca durante la compilación del programa que lo invoca, entonces la biblioteca se denomina biblioteca estática . [2] Una alternativa es crear el ejecutable del programa de forma independiente del archivo de la biblioteca. Las funciones de la biblioteca se conectan después de que se inicia el ejecutable, ya sea en tiempo de carga o en tiempo de ejecución . En este caso, la biblioteca se denomina biblioteca dinámica .
La mayoría de los lenguajes compilados tienen una biblioteca estándar , aunque los programadores también pueden crear sus propias bibliotecas personalizadas. La mayoría de los sistemas de software modernos proporcionan bibliotecas que implementan la mayoría de los servicios del sistema. Estas bibliotecas han organizado los servicios que requiere una aplicación moderna. Como tal, la mayor parte del código utilizado por las aplicaciones modernas se proporciona en estas bibliotecas del sistema.
La idea de una biblioteca informática se remonta a los primeros ordenadores creados por Charles Babbage . Un artículo de 1888 sobre su Motor Analítico sugirió que las operaciones de la computadora podrían perforarse en tarjetas separadas de la entrada numérica. Si estas tarjetas perforadas de operación se guardaran para su reutilización, "poco a poco el motor tendría una biblioteca propia". [3]
En 1947, Goldstine y von Neumann especularon que sería útil crear una "biblioteca" de subrutinas para su trabajo en la máquina IAS , una de las primeras computadoras que aún no estaba operativa en ese momento. [4] Imaginaron una biblioteca física de grabaciones de cables magnéticos , en la que cada cable almacenaría código informático reutilizable. [5]
Inspirándose en von Neumann, Wilkes y su equipo construyeron EDSAC . Un archivador de cinta perforada contenía la biblioteca de subrutinas de esta computadora. [6] Los programas para EDSAC consistían en un programa principal y una secuencia de subrutinas copiadas de la biblioteca de subrutinas. [7] En 1951, el equipo publicó el primer libro de texto sobre programación, La preparación de programas para una computadora digital electrónica , que detallaba la creación y el propósito de la biblioteca. [8]
COBOL incluyó "capacidades primitivas para un sistema bibliotecario" en 1959, [9] pero Jean Sammet las describió como "instalaciones bibliotecarias inadecuadas" en retrospectiva. [10]
JOVIAL tiene un grupo de comunicaciones (COMPOOL), más o menos una biblioteca de archivos de encabezado.
Otro factor importante que contribuyó al concepto de biblioteca moderna llegó en forma de innovación del subprograma de FORTRAN . Los subprogramas FORTRAN se pueden compilar independientemente unos de otros, pero el compilador carecía de un vinculador . Entonces, antes de la introducción de los módulos en Fortran-90, la verificación de tipos entre subprogramas de FORTRAN [NB 1] era imposible. [11]
A mediados de la década de 1960, las bibliotecas de copia y macros para ensambladores eran comunes. A partir de la popularidad de IBM System/360 , también se volvieron comunes las bibliotecas que contienen otros tipos de elementos de texto, por ejemplo, parámetros del sistema.
En OS/360 de IBM y sus sucesores, esto se denomina conjunto de datos particionados .
El primer lenguaje de programación orientado a objetos , Simula , desarrollado en 1965, admitía la adición de clases a bibliotecas a través de su compilador. [12] [13]
Las bibliotecas son importantes en el proceso de vinculación o vinculación de programas , que resuelve referencias conocidas como enlaces o símbolos a módulos de biblioteca. El proceso de vinculación generalmente lo realiza automáticamente un vinculador o programa enlazador que busca en un conjunto de bibliotecas y otros módulos en un orden determinado. Por lo general, no se considera un error si el destino de un enlace se puede encontrar varias veces en un conjunto determinado de bibliotecas. La vinculación se puede realizar cuando se crea un archivo ejecutable (enlace estático) o siempre que el programa se utilice en tiempo de ejecución (enlace dinámico).
Las referencias que se resuelven pueden ser direcciones para saltos y otras llamadas de rutina. Pueden estar en el programa principal, o en un módulo dependiendo de otro. Se resuelven en direcciones fijas o reubicables (desde una base común) asignando memoria de ejecución para los segmentos de memoria de cada módulo al que se hace referencia.
Algunos lenguajes de programación utilizan una función llamada enlace inteligente mediante la cual el enlazador conoce el compilador o está integrado con él, de modo que sabe cómo se usan las referencias externas y el código de una biblioteca que nunca se usa realmente , aunque esté referenciado internamente, puede ser descartado de la aplicación compilada. Por ejemplo, un programa que sólo utiliza números enteros para aritmética, o que no realiza ninguna operación aritmética, puede excluir las rutinas de la biblioteca de punto flotante. Esta función de enlace inteligente puede reducir el tamaño de los archivos de las aplicaciones y reducir el uso de memoria.
Algunas referencias en un programa o módulo de biblioteca se almacenan en una forma relativa o simbólica que no se puede resolver hasta que a todo el código y las bibliotecas se les asignen direcciones estáticas finales. La reubicación es el proceso de ajustar estas referencias y lo realiza el vinculador o el cargador . En general, la reubicación no se puede realizar en bibliotecas individuales porque las direcciones en la memoria pueden variar según el programa que las utiliza y otras bibliotecas con las que se combinan. El código independiente de la posición evita referencias a direcciones absolutas y, por lo tanto, no requiere reubicación.
Cuando la vinculación se realiza durante la creación de un archivo ejecutable u otro archivo objeto, se conoce como vinculación estática o vinculación anticipada . En este caso, la vinculación generalmente la realiza un vinculador , pero también puede realizarla el compilador . [14] Una biblioteca estática , también conocida como archivo , es aquella destinada a estar vinculada estáticamente. Originalmente, sólo existían bibliotecas estáticas. Se debe realizar un enlace estático cuando se recompila cualquier módulo.
Todos los módulos requeridos por un programa a veces están vinculados estáticamente y copiados en el archivo ejecutable. Este proceso y el archivo independiente resultante se conocen como compilación estática del programa. Es posible que una compilación estática no necesite ninguna reubicación adicional si se utiliza memoria virtual y no se desea una aleatorización del diseño del espacio de direcciones . [15]
Una biblioteca compartida u objeto compartido es un archivo destinado a ser compartido por archivos ejecutables y otros archivos de objetos compartidos . Los módulos utilizados por un programa se cargan desde objetos compartidos individuales en la memoria en el momento de la carga o de ejecución , en lugar de ser copiados por un vinculador cuando crea un único archivo ejecutable monolítico para el programa.
Las bibliotecas compartidas se pueden vincular estáticamente durante el tiempo de compilación, lo que significa que las referencias a los módulos de la biblioteca se resuelven y a los módulos se les asigna memoria cuando se crea el archivo ejecutable. [ cita necesaria ] Pero a menudo la vinculación de bibliotecas compartidas se pospone hasta que se cargan. [ dudoso – discutir ]
Aunque originalmente fue pionero en la década de 1960, la vinculación dinámica no llegó a los sistemas operativos más utilizados hasta finales de la década de 1980. Generalmente estaba disponible de alguna forma en la mayoría de los sistemas operativos a principios de la década de 1990. Durante este mismo período, la programación orientada a objetos (OOP) se estaba convirtiendo en una parte importante del panorama de la programación. La programación orientada a objetos con enlace en tiempo de ejecución requiere información adicional que las bibliotecas tradicionales no proporcionan. Además de los nombres y puntos de entrada del código ubicado dentro, también requieren una lista de los objetos de los que dependen. Este es un efecto secundario de uno de los conceptos centrales de la programación orientada a objetos, la herencia, lo que significa que partes de la definición completa de cualquier método pueden estar en diferentes lugares. Esto es más que simplemente enumerar que una biblioteca requiere los servicios de otra: en un verdadero sistema de programación orientada a objetos, es posible que las bibliotecas mismas no se conozcan en el momento de la compilación y varían de un sistema a otro.
Al mismo tiempo, muchos desarrolladores trabajaron en la idea de programas de múltiples niveles, en los que una "pantalla" que se ejecuta en una computadora de escritorio utilizaría los servicios de una computadora central o minicomputadora para el almacenamiento o procesamiento de datos. Por ejemplo, un programa en una computadora basada en GUI enviaría mensajes a una minicomputadora para devolver pequeñas muestras de un enorme conjunto de datos para su visualización. Las llamadas a procedimientos remotos (RPC) ya manejaban estas tareas, pero no existía un sistema RPC estándar.
Pronto, la mayoría de los proveedores de minicomputadoras y mainframes instigaron proyectos para combinar los dos, produciendo un formato de biblioteca OOP que podría usarse en cualquier lugar. Estos sistemas se conocían como bibliotecas de objetos u objetos distribuidos si admitían el acceso remoto (no todos lo hacían). COM de Microsoft es un ejemplo de un sistema de este tipo para uso local. DCOM, una versión modificada de COM, admite acceso remoto.
Durante algún tiempo, las bibliotecas de objetos tuvieron el estatus de "próxima gran novedad" en el mundo de la programación. Hubo una serie de esfuerzos para crear sistemas que se ejecutaran en varias plataformas y las empresas compitieron para intentar que los desarrolladores quedaran atrapados en su propio sistema. Los ejemplos incluyen el modelo de objetos del sistema de IBM (SOM/DSOM), los objetos distribuidos en todas partes (DOE) de Sun Microsystems , los objetos distribuidos portátiles (PDO) de NeXT , el ObjectBroker de Digital , el modelo de objetos componentes de Microsoft (COM/DCOM) y cualquier número de sistemas basados en CORBA .
Las bibliotecas de clases son el equivalente aproximado de programación orientada a objetos de tipos más antiguos de bibliotecas de códigos. Contienen clases , que describen características y definen acciones ( métodos ) que involucran objetos. Las bibliotecas de clases se utilizan para crear instancias u objetos con sus características establecidas en valores específicos. En algunos lenguajes de programación orientada a objetos, como Java , la distinción es clara: las clases suelen estar contenidas en archivos de biblioteca (como el formato de archivo JAR de Java ) y los objetos instanciados residen sólo en la memoria (aunque potencialmente pueden hacerse persistentes en archivos separados). En otros, como Smalltalk , las bibliotecas de clases son simplemente el punto de partida para una imagen del sistema que incluye todo el estado del entorno, las clases y todos los objetos instanciados.
Hoy en día, la mayoría de las bibliotecas de clases se almacenan en un repositorio de paquetes (como Maven Central para Java). El código del cliente declara explícitamente las dependencias de bibliotecas externas en archivos de configuración de compilación (como Maven Pom en Java).
Otra técnica de biblioteca utiliza ejecutables completamente separados (a menudo en alguna forma liviana) y los llama mediante una llamada a procedimiento remoto (RPC) a través de una red a otra computadora. Esto maximiza la reutilización del sistema operativo: el código necesario para soportar la biblioteca es el mismo código que se utiliza para proporcionar soporte de aplicaciones y seguridad para todos los demás programas. Además, dichos sistemas no requieren que la biblioteca exista en la misma máquina, pero pueden reenviar las solicitudes a través de la red.
Sin embargo, este enfoque significa que cada llamada a la biblioteca requiere una cantidad considerable de gastos generales. Las llamadas RPC son mucho más caras que llamar a una biblioteca compartida que ya se ha cargado en la misma máquina. Este enfoque se usa comúnmente en una arquitectura distribuida que hace un uso intensivo de este tipo de llamadas remotas, en particular sistemas cliente-servidor y servidores de aplicaciones como Enterprise JavaBeans .
Las bibliotecas de generación de código son API de alto nivel que pueden generar o transformar código de bytes para Java . Son utilizados por la programación orientada a aspectos , algunos marcos de acceso a datos y para pruebas para generar objetos proxy dinámicos. También se utilizan para interceptar el acceso al campo. [16]
El sistema almacena libfoo.a
archivos libfoo.so
en directorios como /lib
, /usr/lib
o /usr/local/lib
. Los nombres de archivos siempre comienzan con lib
y terminan con un sufijo de .a
( archivo , biblioteca estática) o de .so
(objeto compartido, biblioteca vinculada dinámicamente). Algunos sistemas pueden tener varios nombres para una biblioteca vinculada dinámicamente. Estos nombres suelen compartir el mismo prefijo y tienen diferentes sufijos que indican el número de versión. La mayoría de los nombres son nombres de enlaces simbólicos a la última versión. Por ejemplo, en algunos sistemas libfoo.so.2
sería el nombre de archivo de la segunda revisión importante de la interfaz de la biblioteca vinculada dinámicamente libfoo
. Los .la
archivos que a veces se encuentran en los directorios de la biblioteca son archivos libtool , que el sistema no puede utilizar como tales.
El sistema hereda las convenciones de biblioteca estática de BSD , con la biblioteca almacenada en un .a
archivo, y puede usar .so
bibliotecas vinculadas dinámicamente -style (con el .dylib
sufijo en su lugar). Sin embargo, la mayoría de las bibliotecas en macOS constan de "marcos", ubicados dentro de directorios especiales llamados " paquetes " que envuelven los archivos y metadatos requeridos por la biblioteca. Por ejemplo, un marco llamado MyFramework
se implementaría en un paquete llamado MyFramework.framework
, MyFramework.framework/MyFramework
siendo el archivo de biblioteca vinculado dinámicamente o un enlace simbólico al archivo de biblioteca vinculado dinámicamente en MyFramework.framework/Versions/Current/MyFramework
.
Las bibliotecas de vínculos dinámicos generalmente tienen el sufijo *.DLL
, [17] aunque otras extensiones de nombre de archivo pueden identificar bibliotecas vinculadas dinámicamente con propósitos específicos, por ejemplo, *.OCX
bibliotecas OLE . Las revisiones de la interfaz están codificadas en los nombres de los archivos o abstraídas mediante interfaces de objetos COM . Dependiendo de cómo se compilan, *.LIB
los archivos pueden ser bibliotecas estáticas o representaciones de bibliotecas enlazables dinámicamente necesarias sólo durante la compilación, conocidas como " bibliotecas de importación ". A diferencia del mundo UNIX , que utiliza diferentes extensiones de archivo, al vincular .LIB
un archivo en Windows primero se debe saber si se trata de una biblioteca estática normal o de una biblioteca de importación. En este último caso, .DLL
debe haber un archivo presente en tiempo de ejecución.
probablemente será muy importante desarrollar una "biblioteca" extensa de subrutinas
La biblioteca de generación de códigos de bytes es una API de alto nivel para generar y transformar códigos de bytes JAVA. Lo utilizan marcos de acceso a datos, pruebas y AOP para generar objetos proxy dinámicos e interceptar el acceso a campos.
Las bibliotecas compartidas de Linux son similares a las bibliotecas de enlaces dinámicos (DLL) de Windows. Las DLL de Windows suelen identificarse mediante .dll
extensiones de nombre de archivo.