¿Diferencia entre bibliotecas estáticas y compartidas?

561

¿Cuál es la diferencia entre bibliotecas estáticas y compartidas?

Uso Eclipse y hay varios tipos de proyectos, incluidas las bibliotecas estáticas y las bibliotecas compartidas. ¿Uno tiene una ventaja sobre el otro?

Mohit Deshpande
fuente
44
Wikipedia tiene una buena descripción de la distinción entre bibliotecas estáticas, dinámicas y compartidas.
Adam Holmberg

Respuestas:

746

Las bibliotecas compartidas son archivos .so (o en Windows .dll, o en OS X .dylib). Todo el código relacionado con la biblioteca está en este archivo, y los programas lo usan en tiempo de ejecución. Un programa que usa una biblioteca compartida solo hace referencia al código que usa en la biblioteca compartida.

Las bibliotecas estáticas son archivos .a (o en Windows .lib). Todo el código relacionado con la biblioteca está en este archivo, y está directamente vinculado al programa en tiempo de compilación. Un programa que usa una biblioteca estática toma copias del código que usa de la biblioteca estática y lo hace parte del programa. [Windows también tiene archivos .lib que se usan para hacer referencia a archivos .dll, pero actúan de la misma manera que el primero].

Hay ventajas y desventajas en cada método:

  • Las bibliotecas compartidas reducen la cantidad de código que se duplica en cada programa que hace uso de la biblioteca, manteniendo pequeños los binarios. También le permite reemplazar el objeto compartido con uno que sea funcionalmente equivalente, pero que pueda haber agregado beneficios de rendimiento sin necesidad de volver a compilar el programa que lo utiliza. Sin embargo, las bibliotecas compartidas tendrán un pequeño costo adicional para la ejecución de las funciones, así como un costo de carga en tiempo de ejecución, ya que todos los símbolos de la biblioteca deben estar conectados a las cosas que usan. Además, las bibliotecas compartidas se pueden cargar en una aplicación en tiempo de ejecución, que es el mecanismo general para implementar sistemas de complementos binarios.

  • Las bibliotecas estáticas aumentan el tamaño general del binario, pero significa que no necesita llevar una copia de la biblioteca que se está utilizando. Como el código está conectado en tiempo de compilación, no hay costos de carga adicionales en tiempo de ejecución. El código simplemente está ahí.

Personalmente, prefiero las bibliotecas compartidas, pero uso bibliotecas estáticas cuando necesito asegurarme de que el binario no tenga muchas dependencias externas que puedan ser difíciles de cumplir, como versiones específicas de la biblioteca estándar C ++ o versiones específicas de la biblioteca Boost C ++.

Petesh
fuente
2
"reemplace el objeto compartido con ... funcionalmente equivalente, pero puede [mejorar] el rendimiento": específicamente, funcionalidad equivalente orientada a la persona que llama en el uso semántico de la API (interfaz de programación de aplicaciones: firmas de funciones y variables que incluyen tipos), pero del lado de la implementación la funcionalidad puede diferir en más de perf .: por ejemplo, la función siempre se registra en el archivo -> también se registra en el servidor TCP: puerto esperado en $ MY_APP_LOG_SERVER.
Tony Delroy
1
"[.sos incurre en] un pequeño costo adicional para la ejecución de las funciones" - eso es posible (si los grupos de funciones / pedidos se han optimizado para la localidad de caché en el enlace estático, o debido a rarezas en el sistema operativo / cargador / compilador / arquitectura como cross -segment / large-pointer perf. penals), pero en muchas arquitecturas / configuraciones de compilación, el enlazador dinámico parchea la llamada para crear exactamente los mismos códigos de operación de la máquina de llamadas.
Tony Delroy
2
"Como el código está conectado en tiempo de compilación, no hay costos adicionales de carga en tiempo de ejecución. El código simplemente está ahí". - sí y no ... todo está en la imagen ejecutable lista para ser paginada si la ejecución lo requiere, pero - a partir de una situación en la que su programa no se ha ejecutado lo suficiente como para estar en caché - es posible con bibliotecas compartidas (a veces probable o cierto) que el sistema operativo, un controlador u otro programa en ejecución ya habrá cargado la misma biblioteca compartida que su aplicación quiere usar, en cuyo caso puede estar en caché y su programa se iniciará y ejecutará más rápido.
Tony Delroy
15
Lo que algunas personas no han mencionado es que con las bibliotecas estáticas el compilador sabe qué funciones necesita su aplicación y luego puede optimizarlas al incluir solo esas funciones. ¡Esto puede reducir el tamaño de la biblioteca de forma masiva, especialmente si solo usa un subconjunto realmente pequeño de una biblioteca realmente grande!
jduncanator
1
Esta respuesta podría estar mejor organizada. Sería útil hacer listas de viñetas para pros / contras o una tabla para mostrar las diferencias en cada dimensión donde hay una diferencia.
ElegEnt
377

Una biblioteca estática es como una librería, y una biblioteca compartida es como ... una biblioteca. Con el primero, obtienes tu propia copia del libro / función para llevar a casa; con este último, usted y todos los demás van a la biblioteca para usar el mismo libro / función. Por lo tanto, cualquiera que quiera usar la biblioteca (compartida) necesita saber dónde está, porque tiene que "ir a buscar" el libro / función. Con una biblioteca estática, el libro / función es tuyo, y lo mantienes dentro de tu hogar / programa, y ​​una vez que lo tienes no te importa dónde o cuándo lo obtuviste.

Paul Richter
fuente
70

Simplificado:

  • Enlace estático: un gran ejecutable
  • Enlace dinámico: un pequeño ejecutable más uno o más archivos de biblioteca (archivos .dll en Windows, .so en Linux o .dylib en macOS)
Apilado
fuente
1
Esta respuesta es la mejor para mí porque es práctica. Tiene mucho más sentido que una metáfora que no habla de lo que realmente está sucediendo en la computadora. Después de saber que esto es lo que sucede, intuitivamente conozco todas las otras implicaciones.
off99555
36

Para una biblioteca estática, el enlazador extrae el código de la biblioteca y lo utiliza para construir el ejecutable final en el punto en que compila / construye su aplicación. El ejecutable final no tiene dependencias de la biblioteca en tiempo de ejecución

Para una biblioteca compartida, el compilador / enlazador verifica que los nombres con los que enlaza existen en la biblioteca cuando se crea la aplicación, pero no mueve su código a la aplicación. En tiempo de ejecución, la biblioteca compartida debe estar disponible.

El lenguaje de programación C en sí mismo no tiene un concepto de bibliotecas estáticas o compartidas: son completamente una característica de implementación.

Personalmente, prefiero usar bibliotecas estáticas, ya que simplifica la distribución de software. Sin embargo, esta es una opinión sobre la cual mucha sangre (figurativa) ha sido derramada en el pasado.


fuente
55
+1 para "El lenguaje de programación C en sí mismo no tiene el concepto de bibliotecas estáticas o compartidas, son completamente una característica de implementación".
Tiger
1
Hola anon / @Tiger, ¿por qué dijiste "El lenguaje de programación C en sí mismo no tiene ningún concepto de bibliotecas estáticas o compartidas, son completamente una característica de implementación"? ¿Puede explicar un poco en detalle o señalarme la referencia adecuada?
Sunil Shahu el
@SunilShahu La forma en que se compila y enlaza el programa es específica del compilador y el enlazador que está utilizando, es decir, la implementación específica del lenguaje. Las especificaciones de idioma generalmente no describen cómo se deben implementar o construir los idiomas, solo la funcionalidad, la sintaxis, la gramática, etc.
JC Rocamonde
Los ejemplos más obvios de @SunilShahu podrían ser JavaScript, por ejemplo, donde la especificación (EcmaScript) describe las características del lenguaje, pero son los diferentes proveedores los que envían los intérpretes JS (motores de navegador o Node.js, por ejemplo). Por otro lado, el lenguaje de programación Python tiene varias implementaciones. El oficial es CPython, pero hay otros escritos en otros idiomas.
JC Rocamonde
31

Las bibliotecas estáticas se compilan como parte de una aplicación, mientras que las bibliotecas compartidas no. Cuando distribuye una aplicación que depende de bibliotecas compartidas, las bibliotecas, por ejemplo. los dll en MS Windows deben estar instalados.

La ventaja de las bibliotecas estáticas es que no se requieren dependencias para el usuario que ejecuta la aplicación, por ejemplo, no tienen que actualizar su DLL. La desventaja es que su aplicación es más grande porque la envía con todas las bibliotecas que necesita.

Además de conducir a aplicaciones más pequeñas, las bibliotecas compartidas ofrecen al usuario la posibilidad de usar su propia versión, tal vez mejor, de las bibliotecas en lugar de confiar en una que sea parte de la aplicación.

Tarski
fuente
3
DLL infierno como se ha sabido
gheese
1
"Las bibliotecas estáticas se compilan como parte de una aplicación" ... las bibliotecas estáticas se compilan como bibliotecas estáticas y se vinculan como parte de una aplicación
idclev 463035818
19

La ventaja más significativa de las bibliotecas compartidas es que solo hay una copia de código cargada en la memoria, sin importar cuántos procesos estén usando la biblioteca. Para las bibliotecas estáticas, cada proceso obtiene su propia copia del código. Esto puede conducir a un desperdicio de memoria significativo.

OTOH, una ventaja de las bibliotecas estáticas es que todo está incluido en su aplicación. Por lo tanto, no debe preocuparse de que el cliente tenga la biblioteca (y la versión) correctas disponibles en su sistema.

Jasmeet
fuente
1
La imagen ejecutable es más grande en el disco, así como en la memoria, cuando se usan bibliotecas estáticas.
JustJeff
Eso es correcto, a eso me refería cuando dije que todo está incluido en su aplicación.
Jasmeet
Además, los .soarchivos en los sistemas * nix son una biblioteca un poco compartida (dinámica).
snr
6

Además de todas las otras respuestas, una cosa que no se menciona aún es el desacoplamiento:

Permítanme hablar sobre un código de producción del mundo real, con el que he estado tratando:

Un software muy grande, compuesto por más de 300 proyectos (con Visual Studio), construido principalmente como lib estático y finalmente todos se unen en un gran ejecutable, terminas con los siguientes problemas:

-El tiempo de enlace es extremadamente largo. Puede terminar con más de 15 minutos de enlace, por ejemplo, 10 segundos de tiempo de compilación. Algunas herramientas están de rodillas con un ejecutable tan grande, como las herramientas de verificación de memoria que deben instrumentar el código. Podría caer en alcanzar límites que habían sido vistos como tontos.

Más problemático es el desacoplamiento de su software: en este ejemplo del mundo real, los archivos de encabezados de cada proyecto eran accesibles desde cualquier otro proyecto. Como consecuencia, fue extremadamente fácil para un desarrollador agregar dependencias; se trataba de incluir el encabezado, porque el enlace al final siempre encontrará símbolos. Termina con horribles dependencias de ciclismo y un completo desastre.

Con la biblioteca compartida, es un poco de trabajo extra porque el desarrollador debe editar el sistema de compilación del proyecto para agregar la biblioteca dependiente. Observé que el código de biblioteca compartida tiende a ofrecer una API de código más limpia.

madera de arena
fuente
2
-------------------------------------------------------------------------
|  +-  |    Shared(dynamic)       |   Static Library (Linkages)         |
-------------------------------------------------------------------------
|Pros: | less memory use          |   an executable, using own libraries|
|      |                          |     ,coming with the program,       |
|      |                          |   doesn't need to worry about its   |
|      |                          |   compilebility subject to libraries|
-------------------------------------------------------------------------
|Cons: | implementations of       |   bigger memory uses                |
|      | libraries may be altered |                                     |
|      | subject to OS  and its   |                                     |
|      | version, which may affect|                                     |
|      | the compilebility and    |                                     |
|      | runnability of the code  |                                     |
-------------------------------------------------------------------------
snr
fuente