zoukankan      html  css  js  c++  java
  • C++静态库和动态库

    静态库与动态库

    首先简单介绍一下gcc 指令

    ubuntu 下安装gcc g++ 方法

    sudo apt install gcc g++

    gcc 的简单使用

    建立hello.c 源文件
    gcc hello.c => 生成a.out
    gcc hello.c -o hello => 生成hello
    ./a.out | ./hello 运行

    编译步骤

    1. 预处理 生成.i 文件
    2. 编译 生成.s 文件
    3. 生成目标文件 .o
    4. 链接各个.o 文件生成可执行文件

    gcc常用参数选项

    gcc编译选项 选项的意义
    -E 预处理指定的源文件,不进行编译
    -S 编译指定的源文件,不进行汇编
    -c 编译、汇编指定的源文件,不进行链接
    -o 指定生成文件名字
    -I directory 指定 include 包含文件的搜索目录
    -g 编译时,生成调试信息,该程序可以被调试器调试
    -D 在程序编译的时候,指定一个宏 如打开DEBUG -D DEBUG
    -w 不生成任何警告信息
    -Wall 生成所有警告信息
    -O [123] n的取值范围:0~3。编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
    -l 在程序编译的时候,指定使用的库
    -L 指定编译的时候,搜索的库的路径。
    -fPIC/fpic 生成与位置无关的代码
    -shared 生成共享目标文件。通常用在建立共享库时
    -std 指定编译标准 如-std=c++1z或-std=gnu++17或-std=c++17

    静态库

    • Linux 静态库
      • libxxx.a
        • lib 前缀
        • xxx 库的名字
        • .a 后缀
    • Windows 静态库
      • libxxx.lib

    静态库的制作

    1. 生成 .o 文件

      gcc xxx.c xxx.c xxx.c -c

    2. 使用ar 打包
      1. ar rcs
      2. -r 替换
      3. -c 创建
      4. -s 索引

      ar rcs libxxx.a xxx.o xxx.o xxx.o

    静态库的使用

    引入头文件与需要的静态库libxxx.a (头文件中声明了静态库的接口,libxxx.a为接口的实现)
    gcc main.c -o app -I ./include/ -L 静态库路径 -l 静态库名字

    • -L 静态库路径
    • -l 静态库名字 为libxxx.a 中的xxx

    动态库/共享库

    • Linux 动态库
      • libxxx.so
        • lib 前缀
        • xxx 库的名字
        • .so 后缀
    • Windows 动态库
      • libxxx.dll

    动态库制作

    1. 生成 .o 文件 (与位置无关)

      gcc -c xxx.c xxx.c xxx.c -c -fpic
      -fpic/-fPIC 使用相对地址记录代码位置

    2. gcc -shared xxx.o xxx.o xxx.o -o libcxxx.so

    动态库使用

    引入头文件与需要的动态库libxxx.so 头文件中声明了静态库的接口,libxxx.a为接口的实现)
    $ gcc main.c -o app -I ./include/ -L 动态库路径 -l 动态库名字

    工作原理

    • 静态库在程序编译时会链接到目标代码中,程序运行时不再需要静态库,体积较大。每次编译都需要载入静态代码,内存开销大。
    • 动态库在程序运行时才被载入,程序运行时需要动态库存在,体积较小。系统只需载入一次动态库,不同程序可以得到内存中相同的动态副本,内存开销小。

    解决动态库找不到的问题:

    第一种: 将动态库的绝对路径添加到 LD_LIBRARY_PATH 中

    1. 测试时候使用的, 终端关闭, 设置失效:
      在当前终端中执行: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/库的路径
    2. 长久设置, 将export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/库的路径 写到配置文件中
    • 用户: ~/.bashrc

    添加: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/库的路径

    • 系统: /etc/profile

    添加: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/库的路径

    • 添加完成执行命令, 使修改生效:

    . ~/.bashrc
    . /etc/profile
    source /etc/profile
    . 相当于 source

    第二种: 在 /etc/ld.so.cache 添加动态库路径

    1. 打开文件: /etc/ld.so.conf
    2. 将.so文件路径的目录添加到/etc/ld.so.conf, 更新: sudo ldconfig
    3. /etc/ld.so.conf的作用:记录了程序加载运行期间查找动态链接库时的路径。

    静态库与动态库的区别

    静态库特点总结:

    静态库对函数库的链接是放在编译时期完成的。
    程序在运行时与函数库再无瓜葛,移植方便。
    浪费空间和资源,所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件

    动态态库特点总结:

    动态库把对一些库函数的链接载入推迟到程序运行的时期。
    可以实现进程之间的资源共享。
    程序升级变得简单。(只修改需要升级部分,静态库则需要整个重新编译)

  • 相关阅读:
    Oracle错误——ORA-12704:字符集不匹配
    nodejs 错误问题解决
    windows 卸载 node.js 怎么卸载搜索
    Git安装配置及基本使用(windows)
    破解photoshop cs6 mac
    将text中的数字转换为字符串
    JavaScript 为什么不推荐使用 eval?
    Permission denied (publickey).
    linux 命令
    恢复 git reset -hard 的误操作
  • 原文地址:https://www.cnblogs.com/arvinhuang/p/12707977.html
Copyright © 2011-2022 走看看