静态库和动态库
2015-08-27 21:20
127 查看
首先要明白一个概念,静态库和动态库的目的是为了使二进制代码重用。
静态库:假设一个场景,我们现在做了一个项目A,如果我们希望项目A中的代码能够用于以后的项目B中,该怎么办呢?最简单的想法就是将项目A的各个源文件编译生成的目标文件和其他项目的目标文件拼接起来,有两种方法可以做到这一点
1、将项目A的目标文件转存至项目B的位置,然后进行链接
2、将项目A的目标文件打包成一个二进制的文件--静态库
可以看出,第二种方法更好,静态库可以更简洁的为其他项目提供单个的二进制文件,而不是提供一组分离的目标文件。注意,生成静态库的文件的过程是可逆的,也就是说我们可以向一个静态库中添加目标文件,也可以将静态库文件解压成原来的一组二进制文件。
动态库:再假设一种场景,在多任务的系统中,无论有多少个并行的任务,特性的系统资源总是唯一的,比如键盘和网卡等,如果每一个想访问共享资源的应用程序都需要包含访问资源的控制代码,那么控制代码在内存中会出现多个副本,重复的代码会使系统的效率变得低下。怎么办呢?---避免代码冗余。
正确的解决方案:1、在动态库中提供通用的功能;
2、需要使用通用功能的应用程序只需要在运行时加载动态库即可。
现在通用的解决方案是利用内存映射实现共享,即PIC(位置无关代码position independent code)技术。只需一份加载到某一进程中内存映射的动态库副本,就能映射到任何应用程序的进程中。
创建一个静态库的步骤:
gcc -c first.c second.c
ar rcs libstaticlib.a first.o second.o
创建一个动态库的步骤:
通常来说,构建动态库都需要以下两个选项
-fPIC 编译器选项
-shared 链接器选项
gcc -fPIC -c first.c second.c
gcc -shared first.o second.o -o libdynamiclib.so
注意: -fPIC的PIC是位置无关代码,在PIC出现以前,也能够创建动态库,装载器将动态库加载到进程内存空间中,但是只有第一次加载这个动态库的进程能够使用它。根本原因是,在将动态库加载到进程中前,加载器需要修改动态库的代码段即.text段,使得动态库对于该进程来说是有意义的,但是这种修改是不可逆的,所以一旦动态库被修改再被其他的进程加载后,这个动态库对于后面的进程就是不可用的,而出现PIC后,采用内存映射的技术避免了将加载的动态库代码绑定到第一个加载该动态库的进程中。
参考书籍《高级C/C++编译技术》
静态库:假设一个场景,我们现在做了一个项目A,如果我们希望项目A中的代码能够用于以后的项目B中,该怎么办呢?最简单的想法就是将项目A的各个源文件编译生成的目标文件和其他项目的目标文件拼接起来,有两种方法可以做到这一点
1、将项目A的目标文件转存至项目B的位置,然后进行链接
2、将项目A的目标文件打包成一个二进制的文件--静态库
可以看出,第二种方法更好,静态库可以更简洁的为其他项目提供单个的二进制文件,而不是提供一组分离的目标文件。注意,生成静态库的文件的过程是可逆的,也就是说我们可以向一个静态库中添加目标文件,也可以将静态库文件解压成原来的一组二进制文件。
动态库:再假设一种场景,在多任务的系统中,无论有多少个并行的任务,特性的系统资源总是唯一的,比如键盘和网卡等,如果每一个想访问共享资源的应用程序都需要包含访问资源的控制代码,那么控制代码在内存中会出现多个副本,重复的代码会使系统的效率变得低下。怎么办呢?---避免代码冗余。
正确的解决方案:1、在动态库中提供通用的功能;
2、需要使用通用功能的应用程序只需要在运行时加载动态库即可。
现在通用的解决方案是利用内存映射实现共享,即PIC(位置无关代码position independent code)技术。只需一份加载到某一进程中内存映射的动态库副本,就能映射到任何应用程序的进程中。
创建一个静态库的步骤:
gcc -c first.c second.c
ar rcs libstaticlib.a first.o second.o
创建一个动态库的步骤:
通常来说,构建动态库都需要以下两个选项
-fPIC 编译器选项
-shared 链接器选项
gcc -fPIC -c first.c second.c
gcc -shared first.o second.o -o libdynamiclib.so
注意: -fPIC的PIC是位置无关代码,在PIC出现以前,也能够创建动态库,装载器将动态库加载到进程内存空间中,但是只有第一次加载这个动态库的进程能够使用它。根本原因是,在将动态库加载到进程中前,加载器需要修改动态库的代码段即.text段,使得动态库对于该进程来说是有意义的,但是这种修改是不可逆的,所以一旦动态库被修改再被其他的进程加载后,这个动态库对于后面的进程就是不可用的,而出现PIC后,采用内存映射的技术避免了将加载的动态库代码绑定到第一个加载该动态库的进程中。
参考书籍《高级C/C++编译技术》
相关文章推荐
- iOS中的UIScorllView(滑动控件,时机控制)的基本使用
- mysql查询结果添加序列号
- BZOJ2734: [HNOI2012]集合选数|状压DP
- LeetCode145-Binary-Tree-Postorder-Traversal
- LeetCode144-Binary-Tree-Preorder-Traversal
- Junit(5)趁热打铁
- Rectangle 响应按键
- 循环11~14
- CircuitBreakingException[[FIELDDATA] Data too large, data for [proccessDate] would be larger than li
- python爬虫爬取csdn博客专家所有博客内容
- 5 Longest Palindromic Substring
- Java——反射
- 编程之美-编程判断两个链表(可能含环)是否相交以及相交的第一个结点
- u3d_shader_surface_shader_5
- <!DOCTYPE> 的理解
- Django之第一个app<3>
- php设计模式专题附源码(解释器模式、工厂方法模式、外观模式、装饰模式、建造者模式)
- 基于飞淩OK6410开发板与Ubuntu 10.04 的NFS的配置
- 编程之美-判断两个链表是否相交
- 决策理论(Decision theory)&自动规划和调度(Automated planning and scheduling)(双语)