• linux下库的使用--动态库


      前篇中的静态库有一个明显的缺点,当多个代码公用的库文件为静态库时,需要进行多次拷贝,造成大量重复的代码。主要需求为:

      1、公用一份代码,大大节约执行文件的空间;

      2、对于条件执行的代码,有可能出现代码进入可执行文件,但是却得不到运行的情况;

      3、需要在启动或运行中需要用到时才实时加载进进程空间,并且能够和其他进程共享动态链接的代码

      这都是动态库所具有的特征。动态库中的代码可能被不同的进程引用,库中函数的代码在不同进程中占据的存储空间大小是一样的,但是布局时对应的地址可能是不同的,所以必须要求动态库中的代码不能依赖任何特定布局的元素,这种代码就是位置无关代码(PIC:position independent code)

    一、编辑代码如下:

    #vector.h 
    
    1 #ifndef vector_h
     2 #define vector_h
     3 
     4 void addVec(int *xP, int *yP, int *zP, int Num);
     5 void mulVec(int *xP, int *yP, int *zP, int Num);                                        
     6 
     7 #endif
    
    #addVec.c
    
     1 #include "vector.h"
     2                                                                                         
     3 void addVec(int *xP, int *yP, int *zP, int Num){
     4     for(int i = 0; i < n; i++){
     5         zP[i] = xP[i] + yP[i];
     6     }
     7 
     8     return;
     9 }
    ~   
    
    #mulVec.c
    
     1 #include "vector.h"                                                                     
     2 
     3 void mulVec(int *xP, int *yP, int *zP, int Num){
     4     for(int i = 0; i < n; i++){
     5         zP[i] = xP[i] * yP[i];
     6     }
     7 
     8     return;
     9 }
    
    
    #testVec.c
    
     1 #include <stdio.h>                                                                      
     2 #include "vector.h"
     3 
     4 int x[2] = {1, 2};
     5 int y[2] = {3, 4};
     6 int z[2];
     7 
     8 int main(int argc, char **argv)
     9 {
    10     addVec(x, y, z, 2);
    11     printf("z = [%d %d]
    ", z[0],  z[1]);
    12 
    13     return 0;
    14 }

    二、生成动态库文件:

      1、gcc -shared -fPIC -o libVector.so addVec.c mulVec.c     //生成动态库文件

      2、ls *.so  或  ls | grep .so                  //查看目标文件

      3、file libVector.so                       //查看文件类型

      4、ldd libVector.so                     //查看生成的库文件

      5、nm libVector.so                     //查看生成的库文件包含哪些函数

    三、使用动态库文件:

      gcc testVec.c libVector.so -o testVec           //生成可执行文件,无法执行错误:testVec: error while loading shared libraries: libVector.so: cannot open shared object file: No such file or directory

      ldd testVec                      //查看库引用问题,

    … � gnuC � lib � shared � ldd testVec
            linux-vdso.so.1 (0x00007ffc88c59000)
            libVector.so => not found
            libc.so.6 => /usr/lib/libc.so.6 (0x00007ff632961000)
            /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007ff632b97000)

      就是libVector.so => not found,导致程序无法运行的。

    四、gcc的搜索路径

      手动指定头文件和库文件路径,编译命令:gcc -g -I./include/ -L ./libso/ -lVector testVec.c -o  testVec

      1、头文件搜索路径,默认gcc 对#include <*.h>类的头文件主要从/usr/local/include或/usr/include,这两个是系统默认的无需用户配置

                gcc对#include "*.h"的默认搜索路径是在当前目录下查找,否则就会到系统默认目录下查找

                gcc对#include "*.h"的又是用户自己决定的目录,主要是通过添加编译选项 -I${SELPATH}即可

                gcc对#include "${SELPATH}/*.h"的又是用户自己决定的目录,此时无需添加编译选项

                头文件搜索路径使用环境变量:C_INCLUDE_PATH,经过如下操作

                  C_INCLUDE_PATH=$C_INCLUDE_PATH:$PWD/include

                  echo $C_INCLUDE_PATH  结果:/home/nication/WORKM/studyCode/gnuC/lib/shared/include  验证没错

                  export C_INCLUDE_PATH

                  此时编译只需gcc -g  -L ./libso/ -lVector testVec.c -o  testVec              

      

      2、库文件搜索路径,默认gcc 对库文件主要是-l+文件名,文件名=自己作的库文件名-lib

                gcc对用户自己决定的库目录,主要是通过添加编译选项 -L${SELPATH}即可

                库文件搜索路径使用环境变量:LIBRARY_PATH,经过如下操作

                  LIBRARY_PATH=$LIBRARY_PATH:$PWD/libso

                  echo $LIBRARY_PATH  结果:/home/nication/WORKM/studyCode/gnuC/lib/shared/libso  验证没错

                  export LIBRARY_PATH

                  此时编译只需gcc -g  -I./include/  -lVector testVec.c -o  testVec

      

      如果已经设置过头文件和库文件的搜索路径,编译命令:gcc -g -I./include/ -L ./libso/ -lVector testVec.c -o  testVec,

      也就是说可以:gcc -g  -lVector testVec.c -o  testVec           

    五、运行程序:

      testVec                   //运行结果testVec: error while loading shared libraries: libVector.so: cannot open shared object file : No such file or directory
      需要设置库的载入路径:修改变量LD_LIBRARY_PATH,方法如下:

        LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/libso

        echo $LD_LIBRARY_PATH  结果:/home/nication/WORKM/studyCode/gnuC/lib/shared/libso  验证没错

        export LD_LIBRARY_PATH      导入库载入路径

      再运行: testVec                   //运行结果z = [4 6],终于正确了  
    六、查看testVec代码
      objdump -d testVec,结果:objdump -d testVec

    … � gnuC � lib � shared � objdump -d testVec
    
    testVec:     文件格式 elf64-x86-64
    
    
    Disassembly of section .init:
    
    0000000000001000 <_init>:
        1000:       f3 0f 1e fa             endbr64 
        1004:       48 83 ec 08             sub    $0x8,%rsp
        1008:       48 8b 05 d9 2f 00 00    mov    0x2fd9(%rip),%rax        # 3fe8 <__gmon_start__>
        100f:       48 85 c0                test   %rax,%rax
        1012:       74 02                   je     1016 <_init+0x16>
        1014:       ff d0                   callq  *%rax
        1016:       48 83 c4 08             add    $0x8,%rsp
        101a:       c3                      retq   
    
    Disassembly of section .plt:
    
    0000000000001020 <.plt>:
        1020:       ff 35 e2 2f 00 00       pushq  0x2fe2(%rip)        # 4008 <_GLOBAL_OFFSET_TABLE_+0x8>
        1026:       ff 25 e4 2f 00 00       jmpq   *0x2fe4(%rip)        # 4010 <_GLOBAL_OFFSET_TABLE_+0x10>
        102c:       0f 1f 40 00             nopl   0x0(%rax)
    
    0000000000001030 <printf@plt>:
        1030:       ff 25 e2 2f 00 00       jmpq   *0x2fe2(%rip)        # 4018 <printf@GLIBC_2.2.5>
        1036:       68 00 00 00 00          pushq  $0x0
        103b:       e9 e0 ff ff ff          jmpq   1020 <.plt>
    
    0000000000001040 <addVec@plt>:
        1040:       ff 25 da 2f 00 00       jmpq   *0x2fda(%rip)        # 4020 <addVec>
        1046:       68 01 00 00 00          pushq  $0x1
        104b:       e9 d0 ff ff ff          jmpq   1020 <.plt>
    
    Disassembly of section .text:
    
    0000000000001050 <_start>:
        1050:       f3 0f 1e fa             endbr64 
        1054:       31 ed                   xor    %ebp,%ebp
        1056:       49 89 d1                mov    %rdx,%r9
        1059:       5e                      pop    %rsi
        105a:       48 89 e2                mov    %rsp,%rdx
        105d:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
        1061:       50                      push   %rax
        1062:       54                      push   %rsp
        1063:       4c 8d 05 a6 01 00 00    lea    0x1a6(%rip),%r8        # 1210 <__libc_csu_fini>
        106a:       48 8d 0d 2f 01 00 00    lea    0x12f(%rip),%rcx        # 11a0 <__libc_csu_init>
        1071:       48 8d 3d d1 00 00 00    lea    0xd1(%rip),%rdi        # 1149 <main>
        1078:       ff 15 62 2f 00 00       callq  *0x2f62(%rip)        # 3fe0 <__libc_start_main@GLIBC_2.2.5>
        107e:       f4                      hlt    
        107f:       90                      nop
    
    0000000000001080 <deregister_tm_clones>:
        1080:       48 8d 3d c1 2f 00 00    lea    0x2fc1(%rip),%rdi        # 4048 <__TMC_END__>
        1087:       48 8d 05 ba 2f 00 00    lea    0x2fba(%rip),%rax        # 4048 <__TMC_END__>
        108e:       48 39 f8                cmp    %rdi,%rax
        1091:       74 15                   je     10a8 <deregister_tm_clones+0x28>
        1093:       48 8b 05 3e 2f 00 00    mov    0x2f3e(%rip),%rax        # 3fd8 <_ITM_deregisterTMCloneTable>
        109a:       48 85 c0                test   %rax,%rax
        109d:       74 09                   je     10a8 <deregister_tm_clones+0x28>
        109f:       ff e0                   jmpq   *%rax
        10a1:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
        10a8:       c3                      retq   
        10a9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    
    00000000000010b0 <register_tm_clones>:
        10b0:       48 8d 3d 91 2f 00 00    lea    0x2f91(%rip),%rdi        # 4048 <__TMC_END__>
        10b7:       48 8d 35 8a 2f 00 00    lea    0x2f8a(%rip),%rsi        # 4048 <__TMC_END__>
        10be:       48 29 fe                sub    %rdi,%rsi
        10c1:       48 89 f0                mov    %rsi,%rax
        10c4:       48 c1 ee 3f             shr    $0x3f,%rsi
        10c8:       48 c1 f8 03             sar    $0x3,%rax
        10cc:       48 01 c6                add    %rax,%rsi
        10cf:       48 d1 fe                sar    %rsi
        10d2:       74 14                   je     10e8 <register_tm_clones+0x38>
        10d4:       48 8b 05 15 2f 00 00    mov    0x2f15(%rip),%rax        # 3ff0 <_ITM_registerTMCloneTable>
        10db:       48 85 c0                test   %rax,%rax
        10de:       74 08                   je     10e8 <register_tm_clones+0x38>
        10e0:       ff e0                   jmpq   *%rax
        10e2:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
        10e8:       c3                      retq   
        10e9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    
    00000000000010f0 <__do_global_dtors_aux>:
        10f0:       f3 0f 1e fa             endbr64 
        10f4:       80 3d 4d 2f 00 00 00    cmpb   $0x0,0x2f4d(%rip)        # 4048 <__TMC_END__>
        10fb:       75 33                   jne    1130 <__do_global_dtors_aux+0x40>
        10fd:       55                      push   %rbp
        10fe:       48 83 3d f2 2e 00 00    cmpq   $0x0,0x2ef2(%rip)        # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
        1105:       00 
        1106:       48 89 e5                mov    %rsp,%rbp
        1109:       74 0d                   je     1118 <__do_global_dtors_aux+0x28>
        110b:       48 8b 3d 1e 2f 00 00    mov    0x2f1e(%rip),%rdi        # 4030 <__dso_handle>
        1112:       ff 15 e0 2e 00 00       callq  *0x2ee0(%rip)        # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
        1118:       e8 63 ff ff ff          callq  1080 <deregister_tm_clones>
        111d:       c6 05 24 2f 00 00 01    movb   $0x1,0x2f24(%rip)        # 4048 <__TMC_END__>
        1124:       5d                      pop    %rbp
        1125:       c3                      retq   
        1126:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
        112d:       00 00 00 
        1130:       c3                      retq   
        1131:       66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
        1138:       00 00 00 00 
        113c:       0f 1f 40 00             nopl   0x0(%rax)
    
    0000000000001140 <frame_dummy>:
        1140:       f3 0f 1e fa             endbr64 
        1144:       e9 67 ff ff ff          jmpq   10b0 <register_tm_clones>
    
    0000000000001149 <main>:
        1149:       55                      push   %rbp
        114a:       48 89 e5                mov    %rsp,%rbp
        114d:       48 83 ec 10             sub    $0x10,%rsp
        1151:       89 7d fc                mov    %edi,-0x4(%rbp)
        1154:       48 89 75 f0             mov    %rsi,-0x10(%rbp)
        1158:       b9 02 00 00 00          mov    $0x2,%ecx
        115d:       48 8d 15 ec 2e 00 00    lea    0x2eec(%rip),%rdx        # 4050 <z>
        1164:       48 8d 35 d5 2e 00 00    lea    0x2ed5(%rip),%rsi        # 4040 <y>
        116b:       48 8d 3d c6 2e 00 00    lea    0x2ec6(%rip),%rdi        # 4038 <x>
        1172:       e8 c9 fe ff ff          callq  1040 <addVec@plt>
        1177:       8b 15 d7 2e 00 00       mov    0x2ed7(%rip),%edx        # 4054 <z+0x4>
        117d:       8b 05 cd 2e 00 00       mov    0x2ecd(%rip),%eax        # 4050 <z>
        1183:       89 c6                   mov    %eax,%esi
        1185:       48 8d 3d 78 0e 00 00    lea    0xe78(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
        118c:       b8 00 00 00 00          mov    $0x0,%eax
        1191:       e8 9a fe ff ff          callq  1030 <printf@plt>
        1196:       b8 00 00 00 00          mov    $0x0,%eax
        119b:       c9                      leaveq 
        119c:       c3                      retq   
        119d:       0f 1f 00                nopl   (%rax)
    
    00000000000011a0 <__libc_csu_init>:
        11a0:       f3 0f 1e fa             endbr64 
        11a4:       41 57                   push   %r15
        11a6:       4c 8d 3d 2b 2c 00 00    lea    0x2c2b(%rip),%r15        # 3dd8 <__frame_dummy_init_array_entry>
        11ad:       41 56                   push   %r14
        11af:       49 89 d6                mov    %rdx,%r14
        11b2:       41 55                   push   %r13
        11b4:       49 89 f5                mov    %rsi,%r13
        11b7:       41 54                   push   %r12
        11b9:       41 89 fc                mov    %edi,%r12d
        11bc:       55                      push   %rbp
        11bd:       48 8d 2d 1c 2c 00 00    lea    0x2c1c(%rip),%rbp        # 3de0 <__do_global_dtors_aux_fini_array_entry>
        11c4:       53                      push   %rbx
        11c5:       4c 29 fd                sub    %r15,%rbp
        11c8:       48 83 ec 08             sub    $0x8,%rsp
        11cc:       e8 2f fe ff ff          callq  1000 <_init>
        11d1:       48 c1 fd 03             sar    $0x3,%rbp
        11d5:       74 1f                   je     11f6 <__libc_csu_init+0x56>
        11d7:       31 db                   xor    %ebx,%ebx
        11d9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
        11e0:       4c 89 f2                mov    %r14,%rdx
        11e3:       4c 89 ee                mov    %r13,%rsi
        11e6:       44 89 e7                mov    %r12d,%edi
        11e9:       41 ff 14 df             callq  *(%r15,%rbx,8)
        11ed:       48 83 c3 01             add    $0x1,%rbx
        11f1:       48 39 dd                cmp    %rbx,%rbp
        11f4:       75 ea                   jne    11e0 <__libc_csu_init+0x40>
        11f6:       48 83 c4 08             add    $0x8,%rsp
        11fa:       5b                      pop    %rbx
        11fb:       5d                      pop    %rbp
        11fc:       41 5c                   pop    %r12
        11fe:       41 5d                   pop    %r13
        1200:       41 5e                   pop    %r14
        1202:       41 5f                   pop    %r15
        1204:       c3                      retq   
        1205:       66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
        120c:       00 00 00 00 
    
    0000000000001210 <__libc_csu_fini>:
        1210:       f3 0f 1e fa             endbr64 
        1214:       c3                      retq   
    
    Disassembly of section .fini:
    
    0000000000001218 <_fini>:
        1218:       f3 0f 1e fa             endbr64 
        121c:       48 83 ec 08             sub    $0x8,%rsp
        1220:       48 83 c4 08             add    $0x8,%rsp
        1224:       c3                      retq

      objdump -d addVec.o结果:

    复制代码
    0000000000000000 <addVec>:
       0:   49 89 f9                mov    %rdi,%r9
       3:   49 89 f0                mov    %rsi,%r8
       6:   48 89 d7                mov    %rdx,%rdi
       9:   89 ce                   mov    %ecx,%esi
       b:   b8 00 00 00 00          mov    $0x0,%eax
      10:   eb 11                   jmp    23 <addVec+0x23>
      12:   48 63 d0                movslq %eax,%rdx
      15:   41 8b 0c 90             mov    (%r8,%rdx,4),%ecx
      19:   41 03 0c 91             add    (%r9,%rdx,4),%ecx
      1d:   89 0c 97                mov    %ecx,(%rdi,%rdx,4)
      20:   83 c0 01                add    $0x1,%eax
      23:   39 f0                   cmp    %esi,%eax
      25:   7c eb                   jl     12 <addVec+0x12>
      27:   c3                      retq
    复制代码

      发现addVec.o没完全进入了可执行文件中,只是做好了被调用的准备而以。

    七、动态库工具ldconfig

      该工具主要用来建立动态库的搜索路径的缓存,具有以下几个特征:

      1、默认搜索目录为/usr/lib或/lib

      2、

  • 相关阅读:
    pytorch报错:AttributeError: 'module' object has no attribute '_rebuild_tensor_v2'
    python运行报错:cannot import name 'InteractiveConsole'
    sudo pip3找不到命令
    pytorch入门1——简单的网络搭建
    caffe训练时报错
    python滴啊用caffe时的小坑
    求两个字符串的编辑距离
    归并排序
    复杂度n求数组的第K大值
    牛顿法与拟牛顿法学习笔记(一)牛顿法
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/14161782.html
Copyright © 2020-2023  润新知