• 2.静态库和动态库


    一.相关概念

    静态库.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库,在linux系统之下后缀名为.a  

    动态库(也叫共享库)( .so或.sa ):程序在运行的时候才去链接共享库的代码,多个程序共享使用库的代码。业界一般都使用动态库,因为升级方便

    1、一个与共享库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码

    2、在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该共享库中复制到内存中,这个过程称为动态链接(dynamic linking)

    3、共享库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份共享库被要用到该库的所有进程共用,节省了内存和磁盘空间。

    二.静态库生成

    myadd.h

    extern int myadd(int a, int b);

    myadd.c

    int myadd(int a, int b)
    {
            return a+b;
    }

    test.c

    include <stdio.h>
    #include "../inc/myadd.h"
    
    int main()
    {
    
            int a = myadd(3,4);
            printf("current result is: %d
    ",a);
            return 0;
    }

    1. 生成.o文件

      gcc -c myadd.c -o myadd.o

    2. 将.o文件压成.a文件

      ar rcs libmyadd.a myadd.o

    3. 链接libmyadd.a这个静态库,-L代表在哪个路径之下找这个静态库,后面的.代表当前路径

      gcc -L. main.c -o main.exe -lmyadd

      // 若头文件与.c文件不在同一个目录,-I(大写的i)代表在哪个路径下找这个头文件,后面的../inc指的是上级目录的inc目录下

      gcc -I../inc -L../ main.c -o main.exe -lmyadd

    备注:

    .a文件实际上是.o文件的集合,打个包而已;

    ar是gnu归档工具,rcs表示(replace and create);

    -lmyadd 表示要链接libmyadd.so或者libmyadd.a库文件,如果这两个库同时存在,优先链接libmyadd.so这个动态库。

    三.动态库生成

    1.生成动态库

    -share的意思是告诉GCC编译器,把.c编译成.o然后压成.so
    -fPIC是意思是生成的.so文件在链接时与位置无关,此选项必加

      gcc -shared -fPIC -I./inc ./src/myadd.c -o libmyadd.so

    2.链接动态库

      gcc -L. main.c -o main.exe -lmyadd

    PS: 若运行生成的 main.exe 出现下列错误:

    error while loading shared libraries: libmyadd.so: cannot open shared object file: No such file or directory 则说明系统不知道libmyadd.so放在哪个目录下

    可以cd到用户目录下,如:home/yongdaimi,执行

      vim .bashrc

    在.bashrc的尾部添加下列代码,指定共享库的访问路径即可。:号左边的.代表共享库可以在main.exe所在的当前目录,也可以在用户目录的lib文件夹下(home/yongdaimi/lib)

      export LD_LIBRARY_PATH=.:$HOME/lib:/usr/lib:$LD_LIBRARY_PATH

    备注:

    1.在实际开发过程中,共享库的所在位置是很重要的,可以通过ldd main.exe查看可执行程序链接的各个共享库的位置

      ldd main.exe

      linux-vdso.so.1 => (0x00007fffe27fe000)

      libmyadd.so => /home/yongdaimi/lib/libmyadd.so (0x00007f5d8734f000)

      libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5d86f74000)

      /lib64/ld-linux-x86-64.so.2 (0x00007f5d87553000)

      

    2.也可以通过nm 命令查看当前动态库里包含的函数列表

      nm libmyadd.so  

      0000000000201030 B __bss_start
      0000000000201030 b completed.6973
      w __cxa_finalize@@GLIBC_2.2.5
      0000000000000590 t deregister_tm_clones
      0000000000000600 t __do_global_dtors_aux
      0000000000200e08 t __do_global_dtors_aux_fini_array_entry
      0000000000201028 d __dso_handle
      0000000000200e18 d _DYNAMIC
      0000000000201030 D _edata
      0000000000201038 B _end
      000000000000068c T _fini
      0000000000000640 t frame_dummy
      0000000000200e00 t __frame_dummy_init_array_entry
      0000000000000718 r __FRAME_END__
      0000000000201000 d _GLOBAL_OFFSET_TABLE_
      w __gmon_start__
      0000000000000540 T _init
      w _ITM_deregisterTMCloneTable
      w _ITM_registerTMCloneTable
      0000000000200e10 d __JCR_END__
      0000000000200e10 d __JCR_LIST__
      w _Jv_RegisterClasses
      0000000000000675 T myadd
      00000000000005c0 t register_tm_clones
      0000000000201030 d __TMC_END__

  • 相关阅读:
    Java的 Annotation 新特性
    Java 枚举
    Java 泛型
    Linux kali信息探测以及 Nmap 初体验
    静态导入 ()
    Java foreach循环
    Java 可变参数
    炫酷的CSS3响应式表单
    关于CSS选择器连续性的问题
    简述ECMAScript6新增特性
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/7356643.html
Copyright © 2020-2023  润新知