[Linux] Biblioteca dinámica y estática

prefacio

contenido

1. ¿Por qué hay una biblioteca? 2.
Biblioteca estática 2.1 Generar un archivo .c
    en un archivo .o con el mismo nombre
    
    

    
    
    

  • Biblioteca estática (.a): el programa copia el código binario de la biblioteca en el archivo ejecutable de mi programa cuando el programa se compila y vincula, y la biblioteca estática ya no es necesaria cuando se ejecuta el programa

  • Biblioteca dinámica (.so): el código de la biblioteca dinámica solo se vincula cuando el programa se está ejecutando y el código de la biblioteca es compartido por varios programas

Como la biblioteca de lenguaje c:

  • Biblioteca dinámica libc.so
  • biblioteca estática libc.a

La regla de nomenclatura de la biblioteca es: encabezado lib + nombre de la biblioteca + sufijo elimine el prefijo lib, elimine el sufijo ., y el resto es el nombre de la biblioteca

Hay dos formas de generar programas ejecutables: enlace dinámico y enlace estático

ldd filename # 查看链接方式

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

1. ¿Por qué hay una biblioteca?

Al desarrollar, a menudo usamos código escrito por otros, incluida la compilación del código fuente de otras personas, llamando a bibliotecas de terceros proporcionadas por otros, llamando a interfaces de funciones de red proporcionadas por otros...

inserte la descripción de la imagen aquí

¿Por qué deberíamos usar el código de otra persona?

  • Mejorar la eficiencia del desarrollo
  • Aumentar la solidez del programa

La llamada robustez se refiere a la robustez del programa, y ​​el acoplamiento entre cada módulo es bajo. Para bibliotecas de terceros, creemos que no hay problema. Si hay un error en mi programa, entonces no hay necesidad de sospechar que hay un problema con la biblioteca llamada en sí, pero debe haber un problema con la lógica del código escrito por mí mismo, lo que reduce el alcance del error a ser comprobado. Por supuesto, la biblioteca aquí debe hacer referencia a algunas bibliotecas autorizadas, como bibliotecas estándar como STL.

Bueno, como usar el código de otras personas, es muy importante aprender a empaquetar y usar la biblioteca.

2. Biblioteca estática

Para este experimento, tenemos 5 archivos originales:

add.h
add.c
sub.h
sub.c
main.c

#pragma once
#include <stdio.h>
int add(int x, int y);
#include "add.h"
int add(int x, int y) {
    
    
  return x+y;
}
#pragma once
#include <stdio.h>
int sub(int x, int y);
#include "sub.h"
int sub(int x, int y) {
    
    
  return x-y;
}
#include <stdio.h>
#include "add.h"
#include "sub.h"
int main() {
    
    
  printf("%d\n%d\n", add(20, 10), sub(20, 10));
  return 0;
}

2.1 Genere el archivo .c en un archivo .o con el mismo nombre

Llamar a la biblioteca estática se refiere a vincular el código binario de la biblioteca estática en el archivo ejecutable cuando el programa está vinculado, de modo que no es necesario encontrar la biblioteca estática cuando se ejecuta.

Bueno, dado que la biblioteca estática está vinculada al archivo ejecutable en el paso de vinculación, entonces de acuerdo con

Preprocesamiento - Compilar - Ensamblar - Vincular

Necesitamos completar el paso de ensamblaje. El ensamblaje consiste en convertir el código de ensamblaje en código de máquina, y el archivo generado es un .oarchivo.

gcc -c add.c 
gcc -c sub.c

inserte la descripción de la imagen aquí

2.2 Hacer una biblioteca estática

La esencia de hacer una biblioteca estática es empaquetar varios archivos .o

ar -ac libmymath.a add.o sub.o

inserte la descripción de la imagen aquí

Use ar -tv para ver los archivos incluidos en la biblioteca estática:
inserte la descripción de la imagen aquí

2.3 Uso de bibliotecas estáticas

Metemos los tres archivos add.o sub.o libmymath.a en la carpeta slib

1. Utilice -Iel directorio del archivo de encabezado para traerlo al compilar y vincular main.c

gcc main.c -o main -I ./slib/

inserte la descripción de la imagen aquí
parece que falta algo

2. Use -Lpara traer el directorio donde se encuentra el archivo de la biblioteca

gcc main.c -o main -I ./slib/ -L ./slib/

inserte la descripción de la imagen aquí
parece que falta algo

3. Use -lel nombre de la biblioteca (la parte entre lib y . sufijo)

gcc main.c -o main -I ./slib/ -L ./slib/ -lmymath

En este punto, el ejecutable se genera con éxito:

inserte la descripción de la imagen aquí
correr:
inserte la descripción de la imagen aquí

3. Biblioteca dinámica

  • Un archivo ejecutable vinculado con una biblioteca dinámica contiene solo una tabla de las direcciones de entrada de función que utiliza, no el código de máquina completo del archivo de objeto donde reside la función externa.

  • Antes de que el archivo ejecutable comience a ejecutarse, el sistema operativo copia el código de máquina de la función externa desde la biblioteca dinámica en el disco a la memoria, un proceso llamado vinculación dinámica.

  • Las bibliotecas dinámicas se pueden compartir entre varios programas, por lo que la vinculación dinámica hace que los archivos ejecutables sean más pequeños y ahorra espacio en disco. El sistema operativo utiliza un mecanismo de memoria virtual para permitir que todos los procesos que utilizan la biblioteca compartan una biblioteca dinámica en la memoria física, ahorrando memoria y espacio en disco.

3.1 Haciendo una biblioteca dinámica

1. Generar código independiente de la posición

Esta biblioteca dinámica en sí misma no se carga en ningún área de memoria asignada al área compartida, y cualquier ubicación afectará el cambio relativo de la dirección del código en la biblioteca, lo que dará como resultado que el código de biblioteca no ejecutable de la biblioteca se asigne a el área compartida, y cada proceso la usa. El mismo código, sin desperdicio de memoria

gcc -fPIC -c add.c sub.c

inserte la descripción de la imagen aquí


2. Generar archivos de biblioteca dinámicos

gcc -shared -o libmymath.so add.o sub.o 

inserte la descripción de la imagen aquí


3.2 Generación de archivos ejecutables utilizando bibliotecas dinámicas

gcc main.c -o main -I dlib/ -L dlib/ -lmymath

inserte la descripción de la imagen aquí


3.3 Correr

inserte la descripción de la imagen aquí
La ejecución mainencontró un error, ¿qué pasó?

¿ No especificamos ya 编译el directorio del archivo de encabezado, el directorio del archivo de la biblioteca, el nombre del archivo de la biblioteca cuando estuvimos allí?

Oh, se especificó al compilar, pero ahora está en la fase de ejecución. En la fase de ejecución, no se especifica dónde encontrar el archivo de la biblioteca. Por supuesto, no puedo encontrarlo.

3 soluciones:

  • Copie nuestra libmymath.socopia en la ruta de la biblioteca compartida del sistema, generalmente /usr/lib64o/usr/lib

inserte la descripción de la imagen aquí

  • Agregue el directorio dlib a la variable de entorno LD_LIBRARY_PATH

Aquí hay una variable de entorno: LD_LIBRARY_PATH, que almacena el directorio donde el sistema está predeterminado para encontrar archivos de biblioteca dinámica
inserte la descripción de la imagen aquí
Exportar variables de entorno:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/class101/linux/lesson18/dlib
  • configuración de ldconfig/etc/ld.so.conf.d

Cree un archivo .conf arbitrariamente en el directorio /etc/ld.so.conf.d y escriba el directorio de la biblioteca dinámica en el archivo .conf

echo "/root/class101/linux/lesson18/dlib" > /etc/ld.so.conf.d/test.conf
ldconfig

inserte la descripción de la imagen aquí

4. Algunos detalles

detalle uno

¿Por qué el lenguaje C nunca utiliza explícitamente opciones como -I -L -l al compilar?
1. Gcc encuentra los archivos de encabezado y de biblioteca en la ruta predeterminada 2. Cuando gcc
compila el código C, debe buscar libc de forma predeterminada

¿Y si tampoco queremos usar esas opciones?
Copie el archivo de la biblioteca del archivo de encabezado en la ruta predeterminada -> instalación de la biblioteca

detalle dos

enlace dinámico predeterminado de gcc, si no hay un enlace dinámico, vaya al enlace estático

Makefile

main: main.c    
  gcc -o $@ $^ -I ./dlib -L ./dlib -lmymath    
.PHONY: clean    
clean:    
  rm -f main 

Supongo que te gusta

Origin blog.csdn.net/m0_52640673/article/details/123275558
Recomendado
Clasificación