una tipos sirve que programacion para librerias libreria informatica entre dinamicas dinamica diferencia crear creacion compilar bibliotecas biblioteca c++ c linux dll linker

c++ - tipos - que es una libreria en programacion y para que sirve



¿Diferencia entre objetos compartidos(.so), bibliotecas estáticas(.a) y DLL(.so)? (4)

He estado involucrado en algún debate con respecto a las bibliotecas en Linux, y me gustaría confirmar algunas cosas.

A mi entender (corríjame si me equivoco y editaré mi publicación más adelante), hay dos formas de usar las bibliotecas al crear una aplicación:

  1. Bibliotecas estáticas (archivos .a): en el momento del enlace, se coloca una copia de toda la biblioteca en la aplicación final para que las funciones de la biblioteca estén siempre disponibles para la aplicación que realiza la llamada.
  2. Objetos compartidos (archivos .so): en el momento del enlace, el objeto solo se verifica en su API a través del archivo de encabezado (.h) correspondiente. La biblioteca no se usa realmente hasta el tiempo de ejecución, donde se necesita.

La ventaja obvia de las bibliotecas estáticas es que permiten que toda la aplicación sea autónoma, mientras que la ventaja de las bibliotecas dinámicas es que el archivo ".so" puede ser reemplazado (es decir, en caso de que deba actualizarse debido a una seguridad). error) sin requerir que la aplicación base sea recompilada.

He escuchado que algunas personas distinguen entre los objetos compartidos y las bibliotecas dinámicas vinculadas (DLL), aunque ambos son archivos ".so". ¿Hay alguna distinción entre los objetos compartidos y las DLL cuando se trata del desarrollo de C / C ++ en Linux o cualquier otro sistema operativo compatible con POSIX (es decir, MINIX, UNIX, QNX, etc.)? Me han dicho que una diferencia clave (hasta ahora) es que los objetos compartidos solo se usan en tiempo de ejecución, mientras que los archivos DLL deben abrirse primero utilizando la llamada dlopen () dentro de la aplicación.

Finalmente, también he escuchado que algunos desarrolladores mencionan "archivos compartidos", que, a mi entender, también son bibliotecas estáticas en sí mismas, pero nunca son utilizadas directamente por una aplicación. En cambio, otras bibliotecas estáticas se vincularán con los "archivos compartidos" para extraer algunas de las funciones / recursos (pero no todas) del archivo compartido a la biblioteca estática que se está construyendo.

Gracias a todos por adelantado por su ayuda.

Actualizar

En el contexto en el que me proporcionaron estos términos, se trataba de términos efectivamente erróneos utilizados por un equipo de desarrolladores de Windows que tenían que aprender Linux. Intenté corregirlos, pero las normas de idioma (incorrectas) se atascaron.

  1. Objeto compartido: una biblioteca que se vincula automáticamente a un programa cuando se inicia el programa y existe como un archivo independiente. La biblioteca se incluye en la lista de enlaces en el momento de la compilación (es decir: LDOPTS+=-lmylib para un archivo de biblioteca denominado mylib.so ). La biblioteca debe estar presente en tiempo de compilación, y cuando se inicia la aplicación.
  2. Biblioteca estática: una biblioteca que se fusiona con el programa real en el momento de la creación para una aplicación única (más grande) que contiene el código de la aplicación y el código de la biblioteca que se vincula automáticamente a un programa cuando se crea el programa, y ​​el binario final que contiene ambos el programa principal y la propia biblioteca existen como un único archivo binario autónomo. La biblioteca se incluye en la lista de enlaces en el momento de la compilación (es decir: LDOPTS+=-lmylib para un archivo de biblioteca llamado mylib.a). La biblioteca debe estar presente en tiempo de compilación.
  3. DLL: esencialmente igual que un objeto compartido, pero en lugar de ser incluido en la lista de enlaces en tiempo de compilación, la biblioteca se carga a través de los dlopen() / dlsym() para que la biblioteca no tenga que estar presente en el momento de la compilación El programa para compilar. Además, la biblioteca no necesita estar presente (necesariamente) en el momento de inicio o compilación de la aplicación , ya que solo es necesaria en el momento en que se dlsym llamadas dlopen / dlsym .
  4. Archivo compartido: esencialmente lo mismo que una biblioteca estática, pero se compila con los indicadores "exportar-compartido" y "-fPIC". La biblioteca se incluye en la lista de enlaces en el momento de la compilación (es decir: LDOPTS + = - lmylib S para un archivo de biblioteca llamado mylib S .a). La distinción entre los dos es que este indicador adicional es necesario si un objeto compartido o DLL quiere vincular estáticamente el archivo compartido en su propio código Y ser capaz de hacer que las funciones del objeto compartido estén disponibles para otros programas, en lugar de simplemente usarlas interno a la DLL. Esto es útil en el caso de que alguien le brinde una biblioteca estática y desee volver a empaquetarla como SO. La biblioteca debe estar presente en tiempo de compilación.

Actualización adicional

La distinción entre " DLL " y " shared library " era solo un coloquialismo (perezoso e inexacto) en la empresa en la que trabajé en ese momento (los desarrolladores de Windows se vieron obligados a cambiar al desarrollo de Linux, y el término se atascó), adhiriéndose a las descripciones señalado anteriormente.

Además, el literal " S " final después del nombre de la biblioteca, en el caso de "archivos compartidos" era solo una convención utilizada en esa compañía, y no en la industria en general.


Puedo elaborar los detalles de los DLL en Windows para ayudar a aclarar esos misterios a mis amigos aquí en * NIX-land ...

Una DLL es como un archivo de Objeto Compartido. Ambas son imágenes, listas para cargar en la memoria por el cargador del programa del sistema operativo respectivo. Las imágenes van acompañadas de varios bits de metadatos para ayudar a los enlazadores y cargadores a hacer las asociaciones necesarias y utilizar la biblioteca de código.

Las DLL de Windows tienen una tabla de exportación. Las exportaciones pueden ser por nombre, o por posición de tabla (numérica). El último método se considera "de la vieja escuela" y es mucho más frágil: la reconstrucción de la DLL y el cambio de la posición de una función en la tabla terminarán en un desastre, mientras que no existe un problema real si la vinculación de los puntos de entrada es por nombre. Entonces, olvídelo como un problema, pero tenga en cuenta que está ahí si trabaja con un código de "dinosaurio", como las librerías de terceros.

Las DLL de Windows se crean mediante la compilación y la vinculación, al igual que lo haría con un EXE (aplicación ejecutable), pero la DLL está destinada a no estar sola, al igual que una SO está destinada a ser utilizada por una aplicación, ya sea mediante carga dinámica, o mediante enlace de enlace (la referencia al SO está incorporada en los metadatos del binario de la aplicación, y el cargador de programas del SO cargará automáticamente los SO referenciados). Las DLL pueden hacer referencia a otras DLL, al igual que las SO pueden hacer referencia a otras SO.

En Windows, los archivos DLL harán disponibles solo puntos de entrada específicos. Estos se llaman "exportaciones". El desarrollador puede usar una palabra clave especial del compilador para hacer que un símbolo sea visible externamente (para otros enlazadores y el cargador dinámico), o las exportaciones se pueden enumerar en un archivo de definición de módulo que se usa en el momento del enlace cuando la propia DLL es siendo creado. La práctica moderna es decorar la definición de la función con la palabra clave para exportar el nombre del símbolo. También es posible crear archivos de encabezado con palabras clave que declararán ese símbolo como uno para importar desde una DLL fuera de la unidad de compilación actual. Busque las palabras clave __declspec (dllexport) y __declspec (dllimport) para obtener más información.

Una de las características interesantes de las DLL es que pueden declarar una función de controlador estándar "al cargar / descargar". Cada vez que la DLL se carga o descarga, la DLL puede realizar alguna inicialización o limpieza, según sea el caso. Esto se asigna muy bien a tener una DLL como administrador de recursos orientado a objetos, como un controlador de dispositivo o una interfaz de objeto compartido.

Cuando un desarrollador quiere usar una DLL ya construida, debe hacer referencia a una "biblioteca de exportación" (* .LIB) creada por la desarrolladora de DLL cuando creó la DLL, o debe cargar explícitamente la DLL en tiempo de ejecución y solicitar la dirección del punto de entrada por nombre a través de los mecanismos LoadLibrary () y GetProcAddress (). La mayoría de las veces, la vinculación contra un archivo LIB (que simplemente contiene los metadatos del enlazador para los puntos de entrada exportados de la DLL) es la forma en que se utilizan las DLL. La carga dinámica se reserva normalmente para la implementación de "polimorfismo" o "configurabilidad en tiempo de ejecución" en los comportamientos de los programas (acceso a complementos o funcionalidad definida posteriormente, también conocida como "complementos").

La forma en que Windows hace las cosas puede causar cierta confusión a veces; el sistema utiliza la extensión .LIB para referirse tanto a las bibliotecas estáticas normales (archivos, como los archivos POSIX * .a) y a las bibliotecas de "talón de exportación" necesarias para enlazar una aplicación a una DLL en el momento del enlace. Por lo tanto, uno siempre debe mirar para ver si un archivo * .LIB tiene un archivo * .DLL con el mismo nombre; de lo contrario, es probable que el archivo * .LIB sea un archivo de biblioteca estático y no exporte metadatos de enlace para una DLL.


Siempre he pensado que las DLL y los objetos compartidos son simplemente términos diferentes para la misma cosa: Windows los llama DLL, mientras que en los sistemas UNIX son objetos compartidos, con el término general - biblioteca enlazada dinámicamente - que abarca ambos (incluso la función para abrir un .so en UNIX se llama dlopen() después de ''biblioteca dinámica'').

De hecho, solo están vinculados al inicio de la aplicación, sin embargo, su noción de verificación en el archivo de encabezado es incorrecta. El archivo de encabezado define los prototipos que se requieren para compilar el código que usa la biblioteca, pero en el momento del enlace, el enlazador mira dentro de la biblioteca para asegurarse de que las funciones que necesita están realmente allí. El enlazador debe encontrar los cuerpos de función en algún lugar en el momento del enlace o generará un error. TAMBIÉN lo hace en el tiempo de ejecución, ya que, como señala con razón, la biblioteca podría haber cambiado desde que se compiló el programa. Esta es la razón por la cual la estabilidad de ABI es tan importante en las bibliotecas de plataforma, ya que el cambio de ABI es lo que rompe los programas existentes compilados contra versiones anteriores.

Las bibliotecas estáticas son solo paquetes de archivos de objetos que salen directamente del compilador, al igual que los que usted mismo está construyendo como parte de la compilación de su proyecto, por lo que se introducen y se envían al vinculador exactamente de la misma manera, y los bits no utilizados son cayó exactamente de la misma manera.


Tiene razón en que los archivos estáticos se copian en la aplicación en el momento del enlace, y que los archivos compartidos se verifican en el momento del enlace y se cargan en el tiempo de ejecución.

La llamada dlopen no es solo para objetos compartidos, si la aplicación desea hacerlo en tiempo de ejecución en su nombre, de lo contrario, los objetos compartidos se cargan automáticamente cuando se inicia la aplicación. DLLS y .so son lo mismo. el dlopen existe para agregar aún más capacidades de carga dinámica de grano fino para los procesos. No tiene que usar dlopen para abrir / usar los DLL, eso también sucede al inicio de la aplicación.


Una biblioteca estática (.a) es una biblioteca que puede vincularse directamente con el ejecutable final producido por el vinculador, está contenida en ella y no es necesario tener la biblioteca en el sistema donde se implementará el ejecutable.

Una biblioteca compartida (.so) es una biblioteca que está vinculada pero que no está integrada en el ejecutable final, por lo que se cargará cuando se inicie el ejecutable y debe estar presente en el sistema donde se implementa el ejecutable.

Una biblioteca de enlace dinámico en Windows (.dll) es como una biblioteca compartida (.so) en Linux, pero hay algunas diferencias entre las dos implementaciones relacionadas con el sistema operativo (Windows vs Linux):

Una DLL puede definir dos tipos de funciones: exportadas e internas. Las funciones exportadas están destinadas a ser invocadas por otros módulos, así como desde dentro de la DLL donde están definidas. Las funciones internas normalmente están destinadas a ser llamadas solo desde dentro de la DLL donde están definidas.

Una biblioteca SO en Linux no necesita una declaración de exportación especial para indicar símbolos exportables, ya que todos los símbolos están disponibles para un proceso de interrogación.