Principio de enlace de archivo de encabezado de archivo de biblioteca C ++ (completo)

Sobre el principio de vincular archivos en tiempo de ejecución del programa

La relación entre bibliotecas y archivos de encabezado

Por lo general, tenemos que incluir muchos archivos de encabezado cuando escribimos programas, porque podemos evitar la duplicación de ruedas y la construcción del software no puede ser completada por una sola persona. Pero, ¿sabe cómo se ejecutan las funciones en los archivos de encabezado referenciados? ¡Esto involucrará la biblioteca de enlaces!

La biblioteca tiene dos, uno es 静态链接库, uno es 动态链接库, no importa qué tipo de biblioteca desea usar, debe incluirse en los includearchivos de encabezado apropiados del programa . Revisemos primero el proceso de compilación del programa. Como se muestra abajo:

img

  • Biblioteca estática
   静态库的代码在编译过程中已经被载入可执行程序,因此生成的可执行程序体积较大。静态用.a为后缀,  例如: libhello.a
  • Biblioteca dinámica
   共享库(动态库)的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此生成的可执行程序代码体积较小。
  • Enlace estático
什么是静态链接呢?即在链接阶段,将源文件中用到的库函数与汇编生成的目标文件.o合并生成可执行文件。该可执行文件可能会比较大。这种链接方式的好处是:方便程序移植,因为可执行程序与库函数再无关系,放在如何环境当中都可以执行。

缺点是:文件太大,一个全静态方式生成的简单print文件都有857K。而动态链接生成的一样的可执行文件却只要8.4K
  • Enlace dinámico

Sabemos que con la vinculación estática, el archivo será muy grande y, a menudo, ocupa mucho espacio para implementar una función muy pequeña, y es inconveniente volver a compilar el archivo fuente cada vez que se actualiza el archivo de la biblioteca. Los detalles son los siguientes:

img

Para el programa 1 y el programa 2 compilados estáticamente, se utiliza la biblioteca staticMath. Hay dos archivos de objeto staticMath idénticos en la memoria, lo que es una pérdida de espacio Una vez que hay demasiados programas, es probable que la memoria sea insuficiente.

Una cantidad tan grande de memoria solo puede ejecutar estos pocos programas, lo que realmente no está reconciliado.

Aquí es donde entra en juego la biblioteca dinámica. Echemos un vistazo a los resultados de los enlaces dinámicos:

img

Convención de nomenclatura de bibliotecas

在 linux 下,库文件一般放在/usr/lib和/lib下, 
静态库的名字一般为libxxxx.a,其中 xxxx 是该lib的名称;
动态库的名字一般为libxxxx.so.major.minor,xxxx 是该lib的名称,major是主版本号,minor是副版本号

Ver dependencias de archivos ejecutables

ldd查看程序依赖的.so文件

例如 # ldd /bin/lnlibc.so.6 
        => /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2 
        => /lib/ld- linux.so.2 (0×40000000) 
   可以看到 ln 命令依赖于 libc 库和 ld-linux 库 

使用nm工具,查看静态库和动态库中有那些函数名;

  (T类表示函数是当前库中定义的,U类表示函数是被调用的,在其它库中定义的,W类是当前库中定义,被其它库中的函数覆盖)。
  有时候可能需要查看一个库中到底有哪些函数,nm工具可以打印出库中的涉及到的所有符号,这里的库既可以是静态的也可以是动态的。

g ++

Linux下进行程序设计时,关于库的使用:
一、gcc/g++命令中关于库的参数:
    -shared: 该选项指定生成动态连接库;
    -fPIC:表示编译为位置独立(地址无关)的代码,不用此选项的话,编译后的代码是位置相关的,所以动态载入时,是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
    -L:指定链接库的路径,-L. 表示要连接的库在当前目录中
    -ltest:指定链接库的名称为test,编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
    -Wl,-rpath: 记录以来so文件的路径信息。
    LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。
     当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,
     不过如果没有root权限,那么只能采用修改LD_LIBRARY_PATH环境变量的方法了。 
调用动态库的时候,有几个问题会经常碰到:
    1、有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“

Orden de búsqueda de la biblioteca estática

En segundo lugar, el orden de la ruta de búsqueda al vincular la biblioteca estática:

    1. ld会去找gcc/g++命令中的参数-L;
    1. 再找gcc的环境变量LIBRARY_PATH,它指定程序静态链接库文件搜索路径;
      export LIBRARY_PATH=$LIBRARY_PATH:data/home/billchen/lib
    1. 再找默认库目录 /lib /usr/lib /usr/local/lib,这是当初compile gcc时写在程序内的。

Ruta de búsqueda de biblioteca dinámica

En tercer lugar, la secuencia de la ruta de búsqueda durante la vinculación dinámica y la ejecución:

  • 1.编译目标代码时指定的动态库搜索路径;
    1. 环境变量LD_LIBRARY_PATH指定动态库搜索路径,它指定程序动态链接库文件搜索路径;
      export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:data/home/billchen/lib
    1. La ruta de búsqueda de la biblioteca dinámica especificada en el archivo de configuración /etc/ld.so.conf;
    1. La ruta de búsqueda de biblioteca dinámica predeterminada / lib;
    1. La ruta de búsqueda de biblioteca dinámica predeterminada / usr / lib.

Variable ambiental

 LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径
 LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径 

Problemas de actualización de la biblioteca dinámica:

   在动态链接库升级时,
   不能使用cp newlib.so oldlib.so,这样有可能会使程序core掉;
   而应该使用:
   rm oldlib.so 然后 cp newlib.so oldlib.so
   或者
    mv oldlib.so oldlib.so_bak 然后 cp newlib.so oldlib.so

Link de referencia

Link de referencia

Orden de búsqueda de encabezado

Orden de búsqueda

①Buscar en el directorio actual ②Después buscar en el directorio especificado por * -I * ③Buscar en la variable de entorno * CPLUS_INCLUDE_PATH * de * gcc * (* C_INCLUDE_PATH * se usa en el programa * C *) ④Finalmente busque en el directorio predeterminado de * gcc * / usr / include / usr / local / include /usr/lib/gcc/x86_64-redhat-Linux/4.1.1/include
  • ①Busque primero en el directorio actual
  • ②A continuación, busque el directorio especificado por * -I *
  • ③Environmental *gcc*variables de buscar de nuevo *CPLUS_INCLUDE_PATH*(la C programa lo utiliza *C_INCLUDE_PATH*)
  • ④Finalmente busque el directorio predeterminado de gcc
/usr/include

/usr/local/include

/usr/lib/gcc/x86_64-redhat-Linux/4.1.1/include

referencia

Supongo que te gusta

Origin blog.csdn.net/ahelloyou/article/details/112620353
Recomendado
Clasificación