静态库与动态库

首先简单介绍一下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的作用:记录了程序加载运行期间查找动态链接库时的路径。

静态库与动态库的区别

静态库特点总结:

静态库对函数库的链接是放在编译时期完成的。

程序在运行时与函数库再无瓜葛,移植方便。

浪费空间和资源,所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件

动态态库特点总结:

动态库把对一些库函数的链接载入推迟到程序运行的时期。

可以实现进程之间的资源共享。

程序升级变得简单。(只修改需要升级部分,静态库则需要整个重新编译)

C++静态库和动态库的更多相关文章

  1. C++ 系列:静态库与动态库

    转载自http://www.cnblogs.com/skynet/p/3372855.html 这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择 ...

  2. C++静态库与动态库

    C++静态库与动态库 这次分享的宗旨是--让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一 ...

  3. Linux下Gcc生成和使用静态库和动态库详解(转)

    一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...

  4. Makefile中静态库,动态库的创建和使用以及解压缩命令

    应用层通过操作文件操控硬件 使用制作好的工具链: 刚开始学习时,用一些已经制作好的工具链,使用以下命令解压到gcc-3.4.5-glibc-2.3.6目录 cd /work/tools tar xjf ...

  5. VS中Debug和Realease、及静态库和动态库的区别整理(转)

    原文出自:http://www.cnblogs.com/chensu/p/5632486.html 一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不 ...

  6. Linux下C++静态库、动态库的制作与使用

    参考博文:C++静态库与动态库 >> 静态库 1. 静态库的制作 a) 编辑 name.cpp 和name.h文件 b) $g++ -c name.cpp //注意带参数-c,否则直接编译 ...

  7. 在Linux下如何使用GCC编译程序、简单生成 静态库及动态库

      最近在编写的一个Apache  kafka 的C/C++客户端,,在看他写的 example中,他的编译是用librdkafka++.a和librdkafka.a    静态库编译的,,,而我们这 ...

  8. VS中Debug和Realease、及静态库和动态库的区别整理

    一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程序在代码 ...

  9. Linux下Gcc生成和使用静态库和动态库详解

    参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...

  10. android开发 NDK 编译和使用静态库、动态库 (转)

    在eclipse工程目录下建立一个jni的文件夹 在jni文件夹中建立Android.mk和Application.mk文件 Android.mk文件: Android提供的一种makefile文件, ...

随机推荐

  1. vue 阻止冒泡 @click.stop=

    vue 阻止冒泡 @click.stop= vue中处理冒泡标准姿势 事件修饰符 Vue.js 为 v-on 提供了事件修饰符,修饰符是由点开头的指令后缀来表示的.这些事件修饰符主要有以下几个: st ...

  2. ALSA driver---DPCM

    https://www.kernel.org/doc/html/v4.11/sound/soc/dpcm.html Description Dynamic PCM allows an ALSA PCM ...

  3. npm和yarn使用

    npm和yarn使用 他们都属于js包管理工具,都可以安装包或者模块yarn 是由facebook.google等联合开发推出的 区别: npm 下载包的话 比如npm install,它是按照包的排 ...

  4. (11)nc命令(每周一个linux命令)

    nc(netcat)实用程序几乎可用于所有涉及TCP或UDP的事情.它可以打开TCP连接,发送UDP数据包,监听任意TCP和UDP端口,进行端口扫描,处理IPv4和IPv6.与telnet不同,nc可 ...

  5. python多重继承的属性和方法调用顺序问题和对迭代器的初步理解

    推荐阅读:https://www.cnblogs.com/bigb/p/11650707.html 计算机学习的一个好办法就是自己将代码跑一遍,了解代码的运作顺序和原理(主要弄懂 函数作用,传入参数, ...

  6. volatile 手摸手带你解析

    前言 volatile 是 Java 里的一个重要的指令,它是由 Java 虚拟机里提供的一个轻量级的同步机制.一个共享变量声明为 volatile 后,特别是在多线程操作时,正确使用 volatil ...

  7. Python Django撸个WebSSH操作Kubernetes Pod

    优秀的系统都是根据反馈逐渐完善出来的 上篇文章介绍了我们为了应对安全和多分支频繁测试的问题而开发了一套Alodi系统,Alodi可以通过一个按钮快速构建一套测试环境,生成一个临时访问地址,详细信息可以 ...

  8. Comparing Data-Independent Acquisition and Parallel Reaction Monitoring in Their Abilities To Differentiate High-Density Lipoprotein Subclasses 比较DIA和PRM区分高密度脂蛋白亚类的能力 (解读人:陈凌云)

    文献名:Comparing Data-Independent Acquisition and Parallel Reaction Monitoring in Their Abilities To Di ...

  9. 让 Linux 防火墙新秀 nftables 为你的 VPS 保驾护航

    上篇文章 给大家介绍了 nftables 的优点以及基本的使用方法,它的优点在于直接在用户态把网络规则编译成字节码,然后由内核的虚拟机执行,尽管和 iptables 一样都是基于 netfilter, ...

  10. Python-函数练习题1

    # coding=utf-8 '''定义一个方法get_num(num),num参数是列表类型,判断列表里面的元素为数字类型.其他类型则报错, 并且返回一个偶数列表:(注:列表里面的元素为偶数).'' ...