1.什么是库

lib是编译好的二进制代码,可以被操作系统载入内存执行,一般是预先编译好的函数的集合,可以通过头文件链接到库文件,执行已经编译好的代码段。

库一般分为静态库(static lib,在linux系统一般是.a文件)和动态库(dynamic lib,也叫共享库,在linux系统一般是.so文件)。二者的不同点在于被载入的时间不同:

  • 静态库.a在编译的过程中会被编译到可执行文件,也就是说会增大可执行文件的体积。
  • 动态库则是在执行的过程中才会去读取.so文件,不用编译进可执行程序,因此可执行程序体积较小。缺点是拷贝代码时如果没有.so文件可能会造成无法执行。‘

2.静态库

静态库

程序在编译阶段会把静态库的内容复制到目标文件中,在链接阶段将引用的静态库打包到可执行文件中。因此称为静态链接。这里可以发现,静态链接将静态库直接打包进入可执行文件,那么他的组织形式一定和.o文件类似。

实际上,一个静态库是一组目标文件的集合(.o),很多目标文件被打包成一个文件,并且直接参与链接。

静态库有以下特点:

  • 1.静态库对函数的链接是在编译时完成的
  • 2.程序在运行时不再需要静态库,因为对应的程序段已经被复制到原来的位置,移植方便。
  • 3.可执行文件占用空间较大,因为静态库内容被复制进入了可执行文件编译结果。

创建静态库

  1. linux静态库的创建命名规则:lib[library_name].a,lib为前缀,中间是库名,.a为扩展名。
  2. 创建静态库
    现在有如下代码,一定要把头文件和函数体分开声明,否则使用静态库的时候没有头文件只能猜了哦。
**
* @file: unite_time.h
* @author: mattbaisteins@gmail.com
* @date: 2020-08-03
* @brif:
**/
#ifndef _UNITE_TIME_H
#define _UNITE_TIME_H
#include <ctime>
#include <sys/time.h>
#include <string>
#include <vector>
#include <cstdlib>#define BUFFER_SIZE 4096/** get time yymmdd, eg. 190803* @param void* @return string now_time*/std::string get_time();#endif // end _UNITE_TIME_H
/*** @file: unite_time.cpp* @author: mattbaisteins@gmail.com* @date: 2020-08-03* @brif:**/#include "unite_time.h"#include <ctime>std::string get_time() {time_t raw_time;struct std::tm *time_info;char buffer[BUFFER_SIZE];std::time(&raw_time);time_info = std::localtime(&raw_time);std::strftime(buffer, sizeof(buffer) - 1, "%y%m%d", time_info);return std::string(buffer);}

1.首先把代码先编译成目标文件.o(unite_time.o)

gcc -c unite_time.cpp

2 使用ar工具将目标文件打包成静态库.a文件(libunite_time.a)

ar -crv libunite_time.a unite_time.o

注:ar的用法如下

(1)ar是什么
  ar命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。
  ar命令格式:ar [-] {dmpqrtx} [abcfilNoPsSuvV] [membername] [count] archive files...
  例如我们可以用ar rv libtest.a hello.o hello1.o来生成一个库,库名字是test,链接时可以用-ltest链接。该库中存放了两个模块hello.o和hello1.o。选项前可以有‘-'字符,也可以没有。下面我们来看看命令的操作选项和任选项。现在我们把{dmpqrtx}部分称为操作选项,而[abcfilNoPsSuvV]部分称为任选项。
【注:ar可让您集合许多文件,成为单一的备存文件。在备存文件中,所有成员文件皆保有原来的属性与权限】

2)参数介绍 指令参数
-d  删除库文件中的成员文件。
-m  变更成员文件在库文件中的次序。
-p  显示库文件中的成员文件内容。
-q  将问家附加在库文件末端。
-r  将文件插入库文件中。
-t  显示库文件中所包含的文件。
-x  自库文件中取出成员文件。
选项参数
a<成员文件>  将文件插入库文件中指定的成员文件之后。
b <成员文件>  将文件插入库文件中指定的成员文件之前。
c  建立库文件。
f  为避免过长的文件名不兼容于其他系统的ar指令指令,因此可利用此参数,截掉要放入库文件中过长的成员文件名称。
i<成员文件>  将问家插入库文件中指定的成员文件之前。
o  保留库文件中文件的日期。
s  若库文件中包含了对象模式,可利用此参数建立备存文件的符号表。
S  不产生符号表。
u  只将日期较新文件插入库文件中。
v  程序执行时显示详细的信息。
V  显示版本信息。
ar用来管理一种文档。这种文档中可以包含多个其他任意类别的文件。这些被包含的文件叫做这个文档的成员。ar用来向这种文档中添加、删除、解出成员。成员的原有属性(权限、属主、日期等)不会丢失。实际上通常只有在开发中的目标连接库是这种格式的,所以尽管不是,我们基本可以认为ar是用来操作这种目标链接库(.a文件)的。

(3)ar的常用用法
创建库文件
我不知道怎么创建一个空的库文件。好在这个功能好像不是很需要。通常人们使用“ar cru liba.a a.o"这样的命令来创建一个库并把a.o添加进去。"c"关键字告诉ar需要创建一个新库文件,如果没有指定这个标志则ar会创建一个文件,同时会给出 一个提示信息,"u"用来告诉ar如果a.o比库中的同名成员要新,则用新的a.o替换原来的。但是我发现这个参数也是可有可无的,可能是不同版本的ar 行为不一样吧。实际上用"ar -r liba.a a.o"在freebsd5上面始终可以成功。
加入新成员
使用"ar -r liba.a b.o"即可以将b.o加入到liba.a中。默认的加入方式为append,即加在库的末尾。"r"关键字可以有三个修饰符"a", "b"和"i"。 "a"表示after,即将新成员加在指定成员之后。例如"ar -ra a.c liba.a b.c"表示将b.c加入liba.a并放在已有成员a.c之后; "b"表示before,即将新成员加在指定成员之前。例如"ar -rb a.c liba.a b.c"; "i"表示insert,跟"b"作用相同。
列出库中已有成员
"ar -t liba.a"即可。如果加上"v"修饰符则会一并列出成员的日期等属性。
删除库中成员
"ar -d liba.a a.c"表示从库中删除a.c成员。如果库中没有这个成员ar也不会给出提示。如果需要列出被删除的成员或者成员不存在的信息,就加上"v"修饰符。
从库中解出成员
"ar -x liba.a b.c"
调整库中成员的顺序
使用"m"关键字。与"r"关键字一样,它也有3个修饰符"a","b", "i"。如果要将b.c移动到a.c之前,则使用"ar -mb a.c liba.a b.c"

使用用静态库

1 #include <iostream>2 #include <string>3 #include "unite_time.h"45 int main() {6     std::cout << "test static lib" << std::endl;7     std::cout << get_time() << std::endl;8     return 0;910 }

Linux下使用静态库,只需要在编译的时候,指定静态库的搜索路径(-L选项)、指定静态库名(不需要lib前缀和.a后缀,-l选项)。

g++ test.cpp -L./ -lunite_time -o test

就可以生成可执行文件test啦,,我们执行可执行文件test,可以看到test 二进制包大小是24k,成功生成了libunite_time.a

静态库

3.动态库

动态库

动态库,动态库是在程序运行时被载入引用。 只在程序中做一个标记,当用到被标记的库中的函数时,程序会顺着做的标记找到库,然后调用需要的函数,并不会像静态库一样将库中的所有内容都复制包含进来。

为什么有了静态库还要设计动态库?

  • 首先是空间浪费是静态库的一个问题。我们可以这样想假如某一个人静态库占用1M内存,此时有2000个这样的程序需要用到这个库,那么此时,每个程序都需要将这个静态库中的内容拷贝一份到自己里面,这样内存中就会产生多分库函数,并且这些会占用将近2GB的空间。

  • 另外一个问题是由于静态库对程序的更新、部署和发布带来的麻烦。假如某一个静态库更新了,所有使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,只是一个小小的改动,但是却会导致整个程序重新下载,全量更新)

  • 因此我们需要引入动态库,由于动态库是程序运行时被载入的,不同的程序如果调用相同的库,在内存中里只需要有一份该库的实例,避免了空间的浪费,同时也解决了静态库对程序的更新、部署和发布带来的麻烦,用户只需要更新动态库即可,增量更新。

动态库特点总结:

(1)动态库把对一些库函数的链接载入推迟到程序运行的时期。 (2)可以实现进程之间的资源共享。(因此动态库也称为共享库)(3)将一些程序升级变得简单。(4)甚至可以真正做到链接载入完全由程序员在程序代码中控制(显式调用)。

## 创建动态库
1.linux动态库的命名规则
  动态链接库的名字形式为 libxxx.so,前缀是 lib,后缀名为“.so”;针对于实际库文件,每个共享库都有个特殊的名字“so name”。在程序启动后,程序通过这个名字来告诉动态加载器,该载入哪个共享库;在文件系统中,soname仅是一个链接到实际动态库的链接。对于动态库而言,每个库实际上都有另一个名字给编译器来用。它是一个指向实际库镜像文件的链接文件(lib+soname+.so)。

2.创建动态库(.so)
同样是上面的代码

第一步:生成位置无关的目标文件.o(unite_time.o),此时要加编译器选项-fpic

g++ -fPIC -c unite_time.cpp //-fPIC 创建与地址无关的编译程序(pic,position independent code),是为了能够在多个应用程序间共享。

第二步:生成动态库,此时要加链接器选项-shared

g++ -shared -o libunite_time.so unite_time.o

也可以将上面两步合为一步

g++ -fPIC -shared -o libunite_time.so unite_time.cpp

使用动态库

g++ test.cpp -L./ -lunite_time -o test
动态库

Linux系统在同一目录下有可能找不到动态库位置,那么在执行程序时如何定位动态库的位置呢?

(1) 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loader)。
(2)对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的 DT_RPATH段—环境变LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib 目录找到库文件后将其载入内存。

如何让系统能够找到它?

(1)如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其它操作。
(2)如果安装在其它目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下:

第一步:编辑/etc/ld.so.conf文件,加入库文件所在目录的路径
第二步:运行ldconfig ,该命令会重建/etc/ld.so.cache文件

4使用动态库运行时加载的特性做热更新

根据动态库运行时加载的特性,我们可以在不重新编译可执行文件的情况下,对动态库进行热更新,使得test执行过程中执行热热加载
我们修改一下库函数的内容

/*** @file: unite_time.cpp* @author: mattbaisteins@gmail.com* @date: 2020-08-03* @brif:**/#include "unite_time.h"#include <ctime>std::string get_time() {return "hello world";}

重新生成动态库,不重新编译可执行文件,可以发现结果已经变成了新的动态库内容

动态库热更新

热加载


http://www.taodudu.cc/news/show-4394420.html

相关文章:

  • vs2010MFC D3D播放YUV格式视频详细制作全过程
  • Linux C语言调用C++动态链接库-改
  • 正则环视语法
  • 环视拼接-鱼眼镜头模型
  • AVM环视拼接方法介绍
  • 一文尽览 | 计算机视觉中的鱼眼相机模型及环视感知任务汇总!
  • 360°环视性能倍增,瑞芯微首发全景环视芯片方案
  • php 正则表达式 环视,正则表达式教程五 —— 环视(零宽断言)
  • 汽车环视算法原理及其实现
  • JavaScript--环视
  • SurroundDepth:自监督多摄像头环视深度估计
  • 为降低普及门槛,鑫洋泉将全景环视做成“算法引擎”
  • 鱼眼深度估计!环视近场感知系列之几何预测
  • java正则 环视_Java正则环视和反向引用功能与用法详解
  • AVM 环视拼接方法介绍
  • 正则环视 php,php正则表达式环视详解
  • 正则环视 php,PHP正则之环视功能
  • 正则中的环视
  • 正则 环视 oracle,环视正则 - travler的个人空间 - OSCHINA - 中文开源技术交流社区...
  • AVM环视系统算法框架
  • 正则环视 php,正则高级环视
  • 正则环视 php,正则基础之 环视 Lookaround
  • 正则环视(零宽度断言)
  • 正则表达式——环视
  • AVM环视:一.相机标定及原理
  • 正则表达式——环视(Lookaround)(几分钟学会环视)
  • HTML5+CSS3小实例:炫彩的流光按钮
  • HTML5+CSS3小实例:全屏导航栏菜单
  • HTML5+CSS3小实例:富有弹性的导航栏标签
  • HTML5+CSS3小实例:菜单悬停特效

c/c++静态库和动态库制作相关推荐

  1. Linux中gcc的编译、静态库和动态库的制作

    欢迎大家关注笔者,你的关注是我持续更博的最大动力 Linux中gcc的编译.静态库.动态库 文章目录: 1 gcc的编译过程 1.1 gcc的编译过程 1.2 gcc的常用参数 2 gcc 静态库的制 ...

  2. 关于VS2013下制作和使用静态库和动态库

    关于VS2013下制作和使用静态库和动态库 引言 什么是库:库是写好的现有的,成熟的,可以复用的代码. 所谓静态.动态是指链接.将一个程序编译成可执行程序的步骤: 静态库在链接阶段,会将汇编生成的目标 ...

  3. 关于VS环境下制作和使用静态库和动态库

    转载理由:虽然操作什么的很基础,不过作为初学还是很好的文章,手把手教学 关于VS2013下制作和使用静态库和动态库 引言 什么是库:库是写好的现有的,成熟的,可以复用的代码. 所谓静态.动态是指链接. ...

  4. linux下静态库和动态库的制作与使用

    1.首先先介绍一下什么是静态库.什么是动态库? 静态函数库: 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了 ...

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

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

  6. Linux静态库与动态库的概念及制作

    目录 一.静态库 二.动态库 3.静态库的制作 4.动态库的制作 在日常编程中我们不想让别人看到我们写的源码,但还需要发给对方使用,在这种情况下我们引入了静态库动态库,让对方用调库的方式也可以实现我们 ...

  7. 【四、静态库与动态库(共享库)】揭开链接库的神秘面纱:手把手教你制作静态链接库与动态链接库

    前言 不管是在 Windows 下开发,还是在 Linux 下开发,我们都会经常性的使用一些库文件,这些库文件的特点就是,我们可以看到接口的原型并通过这些接口来调用这个函数的功能,但是我们无法查看这个 ...

  8. 手把手教学制作静态库和动态库

    In life, as in whist, hope nothing from the way card may be dealt to you. Play the card, whatever th ...

  9. Linux下制作和使用静态库和动态库

    写在前面: ldd + 可执行文件 可以查看可执行文件所依赖的库 概述: Linux操作系统支持的函数库分为静态库和动态库,动态库又称共享库.linux系统有几个重要的目录存放相应的函数库,如/lib ...

最新文章

  1. darknet53的网络结构笔记
  2. 使用scanf()函数接收带空格的字符串
  3. 你有多了解hybris ?
  4. 当一个头文件引用另一个头文件中的类~
  5. 通用权限管理系统组件 (GPM - General Permissions Manager) 给信息管理系统加一个初始化的功能,调用存储过程...
  6. 如何禁止网络爬虫频繁爬自己网站
  7. 结队项目之需求分析与原型设计
  8. 什么是防火墙?防火墙的设计主要有哪些类型?
  9. string的operate+=
  10. 每天Leetcode 刷题 初级算法篇-数学问题-3的幂
  11. jQuery has(),not()和filter()函数示例
  12. Magento的基本架构解析
  13. 红米k50 至尊版 解锁bl 获取root教程步骤
  14. 嵌入式软件测试怎么实现自动化测试?
  15. 汉字笔画动图怎么做_隶书基本笔画教程(动态图)
  16. Android开发环境
  17. 服务器空文件夹无法删除怎么办,为什么文件夹删不掉
  18. matlab 非支配排序,NSGA-II快速非支配排序算法理解
  19. linux 以太网 mac,苹果Mac以太网卡的连接速度查看方法
  20. Computer Viruses

热门文章

  1. 求解矩阵Ax=b最小二乘问题
  2. Centos GNOME桌面
  3. win10系统打开更新服务器失败怎么回事,如何修复Windows Update组件以解决Win10无法自动更新的问题?...
  4. java.sql.SQLSyntaxErrorException问题常见解决方案:比如Table xxx doesn‘t exist;Unknown column ‘xxx‘ in ‘where...
  5. HTML和CSS隐藏元素的四种方法
  6. pcs与crmsh命令比较
  7. cmake交叉编译mbedtls,open62541笔记
  8. openbmc-web3:添加语言
  9. 【C++学习笔记2】构造函数、析构函数、函数多态、抽象类、函数模板
  10. matlab2012a到期重新激活