C静态库的创建与使用--为什么要引入静态库?
C源程序需要经过预处理、编译、汇编几个阶段,得到各自源文件对应的可重定位目标文件,可重定位目标文件就是各个源文件的二进制机器代码,一般是.o格式。比如:util1.c、util2.c及main.c三个C源文件,经过预处理器、编译器、汇编器的处理,就可以得到各自的目标文件util1.o,util2.o以及main.o。可重定位目标文件中的地址是从0开始的,需要链接器将若干个可重定位目标文件通过符号解析、重定位等工作,链接成为一个可执行的二进制目标文件。在Linux下,可以使用gcc -c 对源文件进行预处理、编译、汇编,得到目标文件:

可以看到源文件util1.c及util2.c被编译成为了对应的目标文件util1.o及util2.o。在给定的例子中,util1.c和util2.c实际上分别定义的两个函数add和mult,返回两个整数的加法和乘法结果(这么做有点儿蠢,这里只是作为一个例子,讲清楚后面静态库的概念)。两个函数的定义如下:
//util1.c
int add(int a,int b)
{
return a + b;
} //util2.c
int mult(int a,int b)
{
return a * b;
}
util.h中包含了对这两个函数的声明;main.c使用其中的add函数:
#include <stdio.h>
#include "util.h" int main()
{
int a = 5;
int b = 10;
int c = add(a,b);
printf("%d\n",c);
return 0;
}
实际上,所有的编译系统都提供一种机制,将所有相关的目标模块(即目标文件)打包成为一个单独的文件,称为静态库。在Linux中,静态库以一种被称为存档(archive)的文件格式存放在磁盘中。存档文件由后缀.a标识,.a格式的存档文件是一组连接起来的可重定位目标文件的集合,有一个头部用来描述每个成员目标文件的大小和位置。C标准定义了许多静态库,如标准IO操作scanf,printf,字符串操作strcpy等,它们在libc.a库中;一些浮点数学函数如sin,cos等,它们在libm.a库中。
当然,静态库是目标文件的集合,我们也可以将自己定义的函数编译成目标代码,加入静态库中。为了为若干目标文件创建静态库,可以使用ar rcs:

ar rcs 后面紧跟的libutil.a是创建的静态库的名字,通常以lib三个字母开头,后面的util可以自己指定,静态库以.a为后缀。util1.o 及 util2.o 是我们要加入静态库的两个目标文件。这样,就创建了一个静态库文件libutil.a。可以使用ar t来查看静态库文件中包含的目标文件:

接下来,我们在main函数中使用这个库。要在main中使用libutil.a库,需要链接通过编译main.c得到的目标文件main.o和libutil.a:

可以看到,gcc将main.c对应的目标文件与库libutil.a链接起来,得到了可执行文件main。我们执行可执行文件main,得到期望的结果:

注意,main函数中include了头文件util.h,在util.h中对libutil.a中的函数进行了声明。
那么,重点来了,为什么需要引入静态库这种东西呢?将C标准提供的所有库都放在一个可重定位目标模块中不行吗?
事实上是可以的,不过,这种设计有一个很大的缺点是系统中的每个可执行文件都要包含这个整个的大的目标模块的完全副本,这样做很浪费存储空间。比如,C标准的libc.a大约5MB,现在有一台机器装载了15个用到了C标准库的可执行文件,那么这15个可执行文件里每一个实际上都经过链接器的链接,嵌入了libc.a库中的5MB目标代码,而实际上它们可能用到5MB目标代码里的很小一部分(比如,某个目标文件可能只引用了标准库中的strcpy函数),这样,造成了严重的存储空间浪费。而静态库实际上提供了这样一种功能:相关的函数可以被编译为独立的目标模块,然后封装成一个单独的静态库文件,当链接器构造一个可执行文件时,它只“提取”静态库里被应用程序引用的目标模块(换句话说,对于程序中用不到的,链接器不会将它复制到可执行文件中去)。
还有一种方法,就是把每个函数创建独立的可重定位目标文件。这种方法对于应用程序员来说是及其不友好的,因为这种方法要求应用程序员显示地链接需要的目标模块到可执行文件中,这是一个容易出错且耗时的过程。
总结来说,静态库提供了将每一个目标模块独立地打包的功能,并且可以由链接器自动地提取被程序引用的目标模块,这减少了可执行文件在磁盘和内存中的大小,并且大大降低了程序员链接各个目标文件的压力。
C静态库的创建与使用--为什么要引入静态库?的更多相关文章
- ios中静态库的创建和使用、制作通用静态库(Cocoa Touch Static Library)
创建静态库可能出于以下几个理由: 1.你想将工具类代码或者第三方插件快捷的分享给其他人而无需拷贝大量文件.2.你想让一些通用代码处于自己的掌控之下,以便于修复和升级.3.你想将库共享给其他人,但不想让 ...
- Qt——动态库的创建和使用
一.动态库是什么 很多人写程序的人都见过.lib和.dll文件,对动态库也略有耳闻. 生成动态库后可以得到两个文件,后缀名分别是.lib以及.dll. 简而言之,.lib称为导入库,相当于头文件:.d ...
- iOS - 静态库的创建与使用
在日常项目开发中,不论是为了两个公司项目上的业务交流还是为了减少项目的编译时间,有的时候我们会把项目中的私密内容打包成静态库,或者是把项目中变动较少一部分打包成静态库以便提高编译效率,那么下面我们就来 ...
- iOS 中 .a 和 .framework 静态库的创建与 .bundle 资源包的使用
iOS 中 .a 和 .framework 静态库的创建与 .bundle 资源包的使用 前言 开发中经常使用三方库去实现某特定功能,而这些三方库通常又分为开源库和闭源库.开源库可以直接拿到源码,和自 ...
- Qt 共享库(动态链接库)和静态链接库的创建及调用
前言: 编译器 Qt Creator, 系统环境 win7 64 位 1.创建共享库: 新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sh ...
- Windows下静态库与动态库的创建与使用
Windows下静态库与动态库的创建与使用 学习内容:本博客介绍了Windows下使用Visual C++ 6.0制作与使用静态库与动态库的方法. --------CONTENTS-------- 一 ...
- Qt动态库静态库的创建、使用、多级库依赖、动态库改成静态库等详细说明
本文描述的是windows系统下,通过qtcreator在pro文件中添加动态库与静态库的方法: 1.添加动态库(直接添加动态库文件.dll,非子项目) 通过qtcreator创建动态库的方法就不在此 ...
- windows库的创建和使用:静态库+动态库
windows库的创建和使用:静态库+动态库 一.静态库的创建和使用 1. 静态库创建 (1)首先创建projecttest,測试代码例如以下: 1) test.h void test_print ...
- 使用Xcode 5创建Cocoa Touch Static Library(静态库)
转自:http://blog.csdn.net/jymn_chen/article/details/21036035 首先科普一下静态库的相关知识: 程序编译一般需经预处理.编译.汇编和链接几个步骤. ...
- Windows下静态库、动态库的创建和调用过程
静态库和动态库的使用包括两个方面,1是使用已有的库(调用过程),2是编写一个库供别人使用(创建过程).这里不讲述过多的原理,只说明如何编写,以及不正确编写时会遇见的问题. //注:本文先从简单到复杂, ...
随机推荐
- 前端vue单个文件上传支持图片,压缩包以及文件 , 下载完整代码请访问uni-app插件市场址:https://ext.dcloud.net.cn/plugin?id=13066
前端vue单个文件上传支持图片,压缩包以及文件 , 下载完整代码请访问uni-app插件市场址:https://ext.dcloud.net.cn/plugin?id=13066 效果图如下: 使用方 ...
- 构建 JavaScript ChatGPT 插件
聊天插件系统是一种令人兴奋的新方式,可以扩展ChatGPT的功能,纳入您自己的业务数据,并为客户与您的业务互动增加另一个渠道.在这篇文章中,我将解释什么是聊天插件,它们能做什么,以及你如何用JavaS ...
- JVM中的-Xms 、-Xmx 参数该如何设置
在 Java 虚拟机(JVM)中,-Xms 和 -Xmx 都是用来设置 JVM 堆内存大小的参数.其中,-Xms 用于设置 JVM 启动时分配的初始堆内存大小,而 -Xmx 用于设置 JVM 堆内存的 ...
- 电子表格vlookup函数使用
vlookup是常用的辅助查找函数,但是这个函数的参数定义和解释非常的难以理解,即使用向导也很难搞清楚哪个参数是啥意思.放到编程圈里面应该也算bad design的典型了.下面是函数的定义,每次看到这 ...
- DHorse v1.2.1 发布,基于k8s的发布平台
综述 DHorse是一个简单易用.以应用为中心的云原生DevOps系统,具有持续集成.持续部署.微服务治理等功能,无需安装依赖Docker.Maven.Node等环境即可发布Java.Vue.Reac ...
- Federated Learning003
联邦学习笔记--003 2022.11.28周一 今天主要学习了几篇优秀的博客,补充了一些知识. (一)联邦学习面临的挑战 非独立同分布的数据 有限通信带宽 不可靠和有限的设备 什么是Non-IID( ...
- Hexo博客Next6.0版本主题配置(背景图片加载、侧边栏社交小图标设置、设置网站图标)
随机背景图片加载 原理 自动更换背景是修改添加背景的css样式实现 图片来源 https://source.unsplash.com/ 修改背景样式 修改themes\next\source\css\ ...
- 2023年icpc大学生程序设计竞赛-crf
第一次在除郑轻以外的校外的地方比赛,也是第一次出市比赛,赛程也比较长.20号出发的时候遇到一些意外,不过无伤大雅,第一天热身赛平平无奇,晚上的时候补了一下前年icpc的题,一个多小时做了五题,很是自信 ...
- zanePerfor中一套简单通用的Node前后端Token登录机制和github授权登录方式
HI!,你好,我是zane,zanePerfor是一款我开发的一个前端性能监控平台,现在支持web浏览器端和微信小程序端. 我定义为一款完整,高性能,高可用的前端性能监控系统,这是未来会达到的目的,现 ...
- RobotFrameWork环境搭建及使用
RF环境搭建 首先安装python并且配置python环境变量 pip install robotframework pip install robotframework-ride 生产桌面快捷方式 ...