zl程序教程

您现在的位置是:首页 >  系统

当前栏目

linux下库的使用--动态库

Linux -- 动态 使用
2023-09-11 14:22:20 时间

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

  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]\n", 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、