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 consistía en subrutinas (hoy llamadas generalmente funciones). El concepto ahora incluye otras formas de código ejecutable , incluidas clases y datos no ejecutables, como 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 realizar esas llamadas al sistema directamente en el programa.
Una biblioteca puede ser utilizada por varios consumidores independientes (programas y otras bibliotecas). Esto difiere de los recursos definidos en un programa, que normalmente solo pueden ser utilizados por ese programa.
Cuando un consumidor utiliza un recurso de biblioteca, obtiene el valor de la biblioteca sin tener que implementarla por sí mismo. Las bibliotecas fomentan la reutilización de código de manera modular .
Al escribir código que utiliza una biblioteca, un programador solo 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 , una función de biblioteca se invoca a través de la capacidad normal de llamada de función de C. El enlazador genera código para llamar a una función a través del mecanismo de biblioteca si la función está disponible en una biblioteca en lugar de en el programa en sí. [1]
Las funciones de una biblioteca se pueden conectar al programa que la 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 la invoca, la biblioteca se denomina biblioteca estática . [2] Una alternativa es compilar el ejecutable del programa para que esté separado del archivo de la biblioteca. Las funciones de la biblioteca se conectan después de que se inicia el ejecutable, ya sea en el momento de la carga o en el momento de la 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. Dichas bibliotecas han organizado los servicios que requiere una aplicación moderna. Por lo tanto, 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 máquina analítica sugería que las operaciones informáticas podrían perforarse en tarjetas separadas de las entradas numéricas. Si estas tarjetas perforadas de operaciones se guardaran para su reutilización, entonces "poco a poco la máquina 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 computadora temprana que aún no estaba operativa en ese momento. [4] Imaginaron una biblioteca física de grabaciones de cables magnéticos , con cada cable almacenando código de computadora reutilizable. [5]
Inspirados por von Neumann, Wilkes y su equipo construyeron EDSAC . Un archivador de cintas perforadas contenía la biblioteca de subrutinas para 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, The Preparation of Programs for an Electronic Digital Computer , que detallaba la creación y el propósito de la biblioteca. [8]
COBOL incluyó "capacidades primitivas para un sistema de biblioteca" en 1959, [9] pero Jean Sammet las describió como "instalaciones de biblioteca inadecuadas" en retrospectiva. [10]
JOVIAL tiene un pool de comunicaciones (COMPOOL), que es más o menos una biblioteca de archivos de encabezado.
Otro importante aporte al concepto de biblioteca moderna fue la innovación de los subprogramas de FORTRAN . Los subprogramas de FORTRAN se pueden compilar independientemente unos de otros, pero el compilador carecía de un enlazador . Por lo tanto, antes de la introducción de 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 macro para ensambladores eran comunes. A partir de la popularidad del IBM System/360 , las bibliotecas que contenían otros tipos de elementos de texto, por ejemplo, parámetros del sistema, también se hicieron comunes.
En el sistema operativo OS/360 de IBM y sus sucesores, esto se denomina " conjunto de datos particionado" .
El primer lenguaje de programación orientado a objetos , Simula , desarrollado en 1965, admitía la adición de clases a las bibliotecas a través de su compilador. [12] [13]
Las bibliotecas son importantes en el proceso de enlace o vinculación de programas , que resuelve referencias conocidas como enlaces o símbolos a módulos de biblioteca. El proceso de enlace generalmente lo realiza automáticamente un programa enlazador o vinculador que busca un conjunto de bibliotecas y otros módulos en un orden determinado. Por lo general, no se considera un error si un destino de enlace se puede encontrar varias veces en un conjunto determinado de bibliotecas. El enlace se puede realizar cuando se crea un archivo ejecutable (enlace estático) o siempre que se use el programa 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 que depende de otro. Se resuelven en direcciones fijas o reubicables (a partir de una base común) asignando memoria de tiempo de ejecución para los segmentos de memoria de cada módulo al que se hace referencia.
Algunos lenguajes de programación utilizan una característica llamada enlace inteligente , mediante la cual el enlazador conoce o está integrado con el compilador, de modo que sabe cómo se utilizan las referencias externas y el código de una biblioteca que nunca se utiliza realmente , aunque se haga referencia a él internamente, se puede descartar de la aplicación compilada. Por ejemplo, un programa que solo utiliza números enteros para operaciones aritméticas, o que no realiza ninguna operación aritmética, puede excluir rutinas de biblioteca de punto flotante. Esta característica de enlace inteligente puede dar lugar a tamaños de archivo de aplicación más pequeños y a un uso reducido de la 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 asignan direcciones estáticas finales. La reubicación es el proceso de ajuste de estas referencias, y se realiza mediante el enlazador o el cargador . En general, la reubicación no se puede realizar a bibliotecas individuales porque las direcciones en memoria pueden variar según el programa que las use y otras bibliotecas con las que se combinen. El código independiente de la posición evita las referencias a direcciones absolutas y, por lo tanto, no requiere reubicación.
Cuando la vinculación se realiza durante la creación de un ejecutable u otro archivo de objeto, se conoce como vinculación estática o enlace temprano . En este caso, la vinculación generalmente la realiza un enlazador , pero también puede realizarla el compilador . [14] Una biblioteca estática , también conocida como archivo , es una destinada a ser vinculada estáticamente. Originalmente, solo existían bibliotecas estáticas. La vinculación estática debe realizarse cuando se recompilan los módulos.
Todos los módulos que necesita un programa se vinculan estáticamente y se copian en el archivo ejecutable. Este proceso, y el archivo independiente resultante, se conoce 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 aleatorizar el diseño del espacio de direcciones . [15]
Una biblioteca compartida o un objeto compartido es un archivo que está 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 a la memoria en el momento de la carga o en el tiempo de ejecución , en lugar de ser copiados por un enlazador 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 se les asigna memoria a los módulos cuando se crea el archivo ejecutable. [ cita requerida ] Pero a menudo la vinculación de bibliotecas compartidas se pospone hasta que se cargan. [ dudoso – discutir ]
Aunque originalmente se introdujo por primera vez 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. A principios de la década de 1990, ya estaba disponible de alguna forma en la mayoría de los sistemas operativos. Durante este mismo período, la programación orientada a objetos (POO) se estaba convirtiendo en una parte importante del panorama de la programación. La POO con vinculación en tiempo de ejecución requiere información adicional que las bibliotecas tradicionales no proporcionan. Además de los nombres y los puntos de entrada del código que se encuentra en su interior, también requieren una lista de los objetos de los que dependen. Este es un efecto secundario de uno de los conceptos básicos de la POO, 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 POO, las bibliotecas en sí mismas pueden no ser conocidas 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 los programas de múltiples niveles, en los que una "pantalla" que se ejecutaba 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 una interfaz gráfica de usuario enviaría mensajes a una minicomputadora para devolver pequeñas muestras de un conjunto de datos enorme para su visualización. Las llamadas a procedimientos remotos (RPC) ya se encargaban de estas tareas, pero no existía un sistema RPC estándar.
Pronto, la mayoría de los proveedores de minicomputadoras y mainframes iniciaron proyectos para combinar ambos, produciendo un formato de biblioteca OOP que pudiera usarse en cualquier lugar. Dichos sistemas se conocían como bibliotecas de objetos u objetos distribuidos si admitían 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 "la próxima gran novedad" en el mundo de la programación. Hubo una serie de esfuerzos para crear sistemas que pudieran funcionar en todas las plataformas y las empresas compitieron para intentar que los desarrolladores se quedaran con su propio sistema. Algunos ejemplos son el Modelo de objetos del sistema (SOM/DSOM) de IBM , Distributed Objects Everywhere (DOE) de Sun Microsystems, Portable Distributed Objects (PDO) de NeXT , ObjectBroker de Digital , Component Object Model (COM/DCOM) de Microsoft y cualquier cantidad de sistemas basados en CORBA .
Las bibliotecas de clases son el equivalente aproximado en programación orientada a objetos de los tipos más antiguos de bibliotecas de código. 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, ya que las clases a menudo se encuentran en archivos de biblioteca (como el formato de archivo JAR de Java ) y los objetos instanciados residen solo en la memoria (aunque potencialmente se pueden hacer 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.
En la actualidad, 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 las bibliotecas externas en los archivos de configuración de compilación (como Maven Pom en Java).
Otra técnica de biblioteca utiliza archivos ejecutables completamente separados (a menudo en algún formato liviano) y los invoca 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 respaldar la biblioteca es el mismo código que se usa para brindar soporte y seguridad a las aplicaciones de todos los demás programas. Además, estos sistemas no requieren que la biblioteca exista en la misma máquina, sino que pueden reenviar las solicitudes a través de la red.
Sin embargo, este enfoque implica que cada llamada a una biblioteca requiere una cantidad considerable de recursos. Las llamadas RPC son mucho más costosas que llamar a una biblioteca compartida que ya se ha cargado en la misma máquina. Este enfoque se utiliza comúnmente en una arquitectura distribuida que hace un uso intensivo de dichas llamadas remotas, en particular en 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 . Se utilizan en la programación orientada a aspectos , algunos marcos de acceso a datos y para realizar pruebas para generar objetos proxy dinámicos. También se utilizan para interceptar el acceso a campos. [16]
El sistema almacena libfoo.a
y libfoo.so
archiva en directorios como /lib
, /usr/lib
o /usr/local/lib
. Los nombres de archivo 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 múltiples 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 principal 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 enlazadas dinámicamente de estilo - (con el .dylib
sufijo en su lugar). Sin embargo, la mayoría de las bibliotecas en macOS consisten en "marcos", colocados dentro de directorios especiales llamados " paquetes " que envuelven los archivos y metadatos requeridos de 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 enlazado dinámicamente o siendo un enlace simbólico al archivo de biblioteca enlazado dinámicamente en MyFramework.framework/Versions/Current/MyFramework
.
Las bibliotecas de vínculos dinámicos suelen tener el sufijo *.DLL
, [17] aunque otras extensiones de nombre de archivo pueden identificar bibliotecas vinculadas dinámicamente con un propósito específico, por ejemplo, *.OCX
para bibliotecas OLE . Las revisiones de interfaz se codifican en los nombres de archivo o se abstraen 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 que se necesitan solo durante la compilación, conocidas como " bibliotecas de importación ". A diferencia del mundo UNIX , que utiliza diferentes extensiones de archivo, al vincular con .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.
biblioteca de generación de código de bytes es una API de alto nivel para generar y transformar código de bytes JAVA. La utilizan los 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 vínculos dinámicos (DLL) de Windows. Las DLL de Windows suelen identificarse por .dll
extensiones de nombre de archivo.