GNU/Linux >> Tutoriales Linux >  >> Linux

Cómo funciona el enlace dinámico, su uso y cómo y por qué haría un dylib

La principal diferencia es que incluye bibliotecas vinculadas estáticas con su aplicación. Están vinculados cuando construyes tu aplicación. Las bibliotecas dinámicas están vinculadas en tiempo de ejecución, por lo que no necesita incluirlas con su aplicación. En estos días, las bibliotecas dinámicas se utilizan para reducir el tamaño de las aplicaciones al tener muchas bibliotecas dinámicas en la computadora de todos.

Las bibliotecas dinámicas también permiten a los usuarios actualizar las bibliotecas sin reconstruir las aplicaciones cliente. Si se encuentra un error en una biblioteca que usa en su aplicación y está vinculada estáticamente, deberá reconstruir su aplicación y volver a publicarla para todos sus usuarios. Si se encuentra un error en una biblioteca vinculada dinámicamente, todos sus usuarios solo necesitan actualizar sus bibliotecas y su aplicación no necesita una actualización.


Cuando se compila un programa en C++. Debe tener referencias a las funciones y el código de la biblioteca de C++ (digamos, por ejemplo, el código de la biblioteca).

Supongamos que tenemos una biblioteca compartida hipotética llamada libdyno.so . Eventualmente podrá echar un vistazo dentro usando objdump o nm .

objdump --syms libdyno.so

Puede hacer esto hoy en su sistema con cualquier biblioteca compartida. objdump en un MAC se llama gobjdump y viene con cerveza en el binutils paquete. Prueba esto en una Mac...

gobjdump --syms /usr/lib/libz.dylib

Ahora puede ver que los símbolos están contenidos en el objeto compartido. Cuando link con el objeto compartido normalmente usas algo como

g++ -Wall -g -pedantic -ldyno DynoLib_main.cpp -o dyno_main

Tenga en cuenta el -ldyno en ese comando. Esto le dice al compilador (realmente el enlazador ld) que busque un archivo de objeto compartido llamado libdyno.so donde normalmente los busca. Una vez que encuentra ese objeto, puede encontrar los símbolos que necesita. No hay dependencia circular porque usted, el desarrollador, solicitó que se cargara la biblioteca dinámica especificando el -l bandera.

¿Cómo y cuándo usarías una biblioteca dinámica? Cómo haces uno? Como en cuál es el comando de compilación específico que se usa para producir dicho archivo a partir de un archivo .cpp estándar

Cree un archivo llamado DynoLib.cpp

#include "DynoLib.h"
DynamicLib::DynamicLib() {}
int DynamicLib::square(int a) {
  return a * a;
}

Cree un archivo llamado DynoLib.h

#ifndef DYNOLIB_H
#define DYNOLIB_H
class DynamicLib {
  public:
  DynamicLib();
  int square(int a); 
};
#endif

Compílelos para que sean una biblioteca compartida de la siguiente manera. Esto es específico de Linux...

g++ -Wall -g -pedantic -shared -std=c++11 DynoLib.cpp -o libdyno.so

Ahora puede inspeccionar este objeto usando el comando que di antes, es decir,

objdump --syms libdyno.so

Ahora cree un archivo llamado DynoLib_main.cpp que se vinculará con libdyno.so y use la función que acabamos de definir en él.

#include "DynoLib.h"    
#include <iostream>     
using namespace std;
int main(void) {
  DynamicLib *lib = new DynamicLib();
  std::cout << "Square " << lib->square(1729) << std::endl;
  return 1;
}

Compílalo de la siguiente manera

g++ -Wall -g -pedantic -L. -ldyno DynoLib_main.cpp -o dyno_main
./dyno_main
Square 2989441

También puede echar un vistazo al binario principal usando nm . A continuación, veo si hay algo con la cadena square en él, es decir, está el símbolo que necesito de libdyno.so referenciado de alguna manera en mi binario.

nm dyno_runner |grep square
U _ZN10DynamicLib6squareEi

La respuesta es sí. La mayúscula U significa indefinido, pero este es el nombre del símbolo para nuestro método cuadrado en la clase DynamicLib que creamos anteriormente. El nombre de aspecto extraño se debe a la manipulación de nombres, que es un tema propio.

¿Cómo sé a cuáles enlazar estáticamente como lo haría con un archivo normal.o y cuáles se supone que deben enlazarse dinámicamente?

No necesitas saberlo. Usted especifica con qué desea vincular y deja que el compilador (y el vinculador, etc.) haga el trabajo. Tenga en cuenta el -l bandera nombra la biblioteca y el -L le dice dónde mirar. Hay un artículo decente sobre cómo el compilador encuentra algo aquí

Opción de enlace gcc -L:formas alternativas de especificar la ruta a la biblioteca dinámica

O echa un vistazo a man ld .

¿Para qué sirven las banderas -L y -l? ¿Qué significa especificar, por ejemplo, un indicador -lusb en la línea de comando?

Ver el enlace de arriba. Esto es de man ld ..

-L directorio de búsqueda

Agregue path searchdir a la lista de rutas en las que ld buscará bibliotecas de archivo y scripts de control de ld. Puede usar esta opción cualquier número de veces. Los directorios se buscan en el orden en que se especifican en la línea de comando. Los directorios especificados en la línea de comando se buscan antes que los directorios predeterminados. Todas las opciones -L se aplican a todas las opciones -l, independientemente del orden en que aparezcan las opciones. Las opciones -L no afectan cómo ld busca un linkerscript a menos que se especifique la opción -T.`

Si logró llegar aquí, vale la pena aprender sobre el enlazador, es decir, ld. Desempeña un trabajo importante y es fuente de mucha confusión porque la mayoría de las personas comienzan a trabajar con un compilador y piensan que compiler == linker y esto no es cierto.


Linux
  1. Cómo administrar el inventario de hosts estáticos y dinámicos de Ansible

  2. Por qué obtienes cp:error de directorio omitido en Linux y cómo resolverlo

  3. ¿Carga de bibliotecas compartidas y uso de RAM?

  4. ¿Cómo restablecer todas las preferencias de Rhythmbox y la información de la biblioteca?

  5. ¿Por qué hay una discrepancia en el uso del disco informado por df y du?

Cómo hacer un servidor TeamSpeak en Linux, Windows y macOS

Cómo hacer un USB de arranque múltiple en Linux y Windows

¿Qué es un Homelab y por qué debería tener uno?

¿Cómo verificar si una biblioteca compartida está instalada?

¿Por qué y cómo se pueden ejecutar algunas bibliotecas compartidas, como si fueran ejecutables?

¿Cómo haces que sea obvio que estás en un sistema de producción?