0.引言

当进行C语言的编写时,想要查看标准库的某个函数是怎样实现的,比如 stdio.h 里的 printf 函数,跳转后只能看见函数声明,而无法跳转到函数的定义处,为什么无法查看函数的定义,这就涉及到库文件使用。

1.库文件是什么

C程序由 .c 文件最终变成可执行文件要经历预编译,编译,汇编和链接过程,在 Linux 下不同的过程分别生成如下文件 .i,.s,.o 和最终的可执行文件。而库文件就是一组预先编译好的函数的集合,它由 .o 文件生成,而 .o 是一个二进制文件,里面的内容是无法直接理解的,这也是为什么查看不了库中函数的定义,不能看,只能用。Linux 中库的位置一般在 /lib,/usr/lib 和 /usr/lib64 下,而库的头文件一般放在 /usr/include 下。库有两种,一种是静态库,命名形式是 libxx.a,一种是动态库(又叫共享库),命名形式是 libxx.so

2.静态库的生成与使用

2.1.静态库的生成

创建两个 .c 文件和一个 .h 文件,其中 add.c 和 mul.c 文件中包含函数的定义,foo.h 文件中包含函数的声明,具体内容如下。

首先将需要生成库文件的所有 .c 文件编译生成 .o 文件。

利用 ar 命令将所有 .o 文件生成静态库,需要三个参数:c 创建库,r 将方法添加到库中,v 显示过程。

其中,libfoo.a 就是所生成的静态库。

2.2.静态库的使用

编写一个 main.c 文件,其中调用 add 和 mul 两个函数。

直接利用 libfoo.a 和 main.c 文件生成可执行文件,涉及到两个参数:-L 指定所使用的静态库的位置,-l 指定静态库的名字(去掉静态库名字里的前缀 lib 和后缀 .a)。

3.动态库的生成与使用

3.1.动态库的生成

同样利用 add.c 和 mul.c 来生成动态库,其中 foo.h 中是函数的声明,add.c 和 mul.c 中是函数的定义。

首先将需要生成库文件的所有 .c 文件编译成 .o 文件。

使用 gcc 命令和所有 .o 文件来生成动态库。

其中,libfoo.so 就是所生成的动态库。

3.2.动态库的使用

编写一个 main.c 文件,其中调用 add 和 mul 两个函数。

直接利用 libfoo.so 和 main.c 文件生成可执行文件,涉及到两个参数:-L 指定所使用的动态库的位置,-l 指定动态库的名字(去掉动态库名字里的前缀 lib 和后缀 .so)。需要注意的一点是,如果库的存储路径下存在同名的静态库和动态库,gcc 默认使用动态库。

gcc 命令执行完之后会生成可执行程序 main,执行 main 会出现报错。

原因是程序运行时加载动态库,找不到对应的动态库文件 libfoo.so,这是由于虽然用参数 -L 指定了路径,但系统仍然会按照默认方式去存储库的标准位置(/lib 或者 /usr/lib)加载动态库,而不会在当前位置中查找,解决该问题有两种方式:1.将生成的动态库拷贝到 /usr/lib 下,再执行 gcc 命令;2.修改环境变量 LD_LIBRARY_PATH 来指定加载动态库的路径。
方式一:

后面两条命令将动态库 libfoo.so 移出来,并检查 /usr/lib 路径下不存在 libfoo.h。

方式二:
修改环境变量 LD_LIBRARY_PATH。

其中主要涉及到的命令有

export LD_LIBRARY_PATH=.    //添加环境变量(赋值运算符两边不要有空格)
echo $LD_LIBRARY_PATH       //查看环境变量的值
unset LD_LIBRARY_PATH       //删除环境变量

4.静态库与动态库的区别

首先利用相同的程序 add.c mul.c 生成 .o 文件,分别按之前的步骤生成静态库 libfoo1.a 和动态库 libfoo2.so,并将动态库 libfoo2.so 移动到 /usr/lib 下。然后,使用相同的 main.c 文件,利用 gcc 命令生成可执行文件 main1 (使用静态库 libfoo1.a 生成) main2 (使用动态库 libfoo2.so 生成),最后查看两个可执行文件的大小可以发现由静态库生成的可执行文件要比由动态库生成的可执行文件大。

原因是,静态库在链接时将用到的方法包含到最终的可执行文件中,而动态库不包含,只做标记,在程序运行时才动态加载,所以生成的可执行文件更小。由于上面这个原因,每个使用静态库的应用程序都需要拷贝静态库到可执行文件中,所以用静态库生成的可执行程序比较大,一旦链接完成,在执行程序的时候就不需要原来的静态库;而动态库在链接的时候并没有被拷贝到可执行文件中,只是做了标记,程序运行时才动态加载,因此可执行程序比较小,然而,程序运行时需要运行环境提供相应的动态库。
动态库相比于静态库的优点,使用动态库更有利于程序的更新与升级,不必重新编译整个可执行文件,只需要用新版本的动态库替换掉旧版本的动态库即可。

库文件:静态库与动态库的生成和使用相关推荐

  1. 【Android NDK 开发】Android.mk 配置静态库 ( Android Studio 配置静态库 | 配置动态库与静态库区别 | 动态库与静态库打包对比 )

    文章目录 I . Android Studio 中使用 Android.mk 配置静态库 总结 II . 第三方动态库来源 III . 配置 Android.mk 构建脚本路径 IV . 预编译 第三 ...

  2. 【Android 逆向】x86 汇编 ( 使用 IDA 解析 x86 架构的动态库文件 | 使用 IDA 打开动态库文件 | IDA 中查找指定的方法 )

    文章目录 一.使用 IDA 打开动态库文件 二.IDA 中查找指定的方法 一.使用 IDA 打开动态库文件 分析 Android SDK 中的 x86 架构的动态库 , 动态库位置 : D:\001_ ...

  3. vs项目中头文件(.h)静态库(.lib)和 动态库(.dll )的路径和配置

    在程序开发中,很多时候需要用到别人开发的工具包,如OpenCV和itk.一般而言,在vs中,很少使用源文件,大部分是使用对类进行声明的头文件(.h)和封装了类的链接库(静态.lib或动态.dll).如 ...

  4. 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 拷贝 lib7zr.so 动态库头文件到 Android 工程中 | 配置 CMakeLists.txt 构建脚本 )

    文章目录 一.拷贝 p7zip 源码中的头文件到 Android Studio 项目中 二.配置 CMakeLists.txt 构建脚本 1.导入动态库 2.导入头文件 三.完整 CMakeLists ...

  5. 静态库(lib)和动态库(dll)的使用

    静态库(lib)和动态库(dll)的理解与使用 前言 一.函数重载的理解 二.extern "C" 的理解 三.静态库的调用 1.静态库的生成 2.静态库的调用 四.动态库的调用 ...

  6. 【Linux】Linux下静态库(.a)和动态库(.so)的制作和使用

    如有错误,欢迎大家指正,感谢! ​​​​​​​目录 一.程序工作过程简单介绍 1. 安装GCC 2. 源程序工作流程 3. 使用示例 4. gcc常用的编译参数选项 二.静态库的制作及使用 1. 库是 ...

  7. 静态库、动态库、静态链接、动态链接、系统运行库混合、MD MT默认库冲突问题

    一.静态库项目 静态库lib:(注意和"静态运行库"区分)   就是.lib文件,一个.c或.cpp会编译成一个.obj,多个.obj可以组合成一个.lib库.lib=多个obj. ...

  8. 软件库Library之静态库\动态库和静态加载\动态加载

    软件库Library之静态库\动态库和静态加载\动态加载 动态库之导入库 https://blog.csdn.net/wallaceli1981/article/details/5740718 * 动 ...

  9. 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 测试 lib7zr.so 动态库调用 )

    文章目录 一.拷贝 p7zip 源码中的头文件到 Android Studio 项目中 二.完整代码示例 1.Java 层代码 2.JNI 层代码 3.日志头文件 4.执行结果 四.参考资料 前置博客 ...

  10. linux 动态库 软链接,Linux操作系统下动态库的生成及链接方法

    下动态库文件的扩展名为".so"(Shared Object).按照约定,所有动态库文件名的形式是libname.so(可能在名字中加入版本号).这样,线程函数库被称作 libth ...

最新文章

  1. 在NewLisp中实现匿名函数的递归
  2. ubuntu16.04开机卡死解决方案
  3. sizebox模型下载_彻底弄懂CSS盒模型BoxModel
  4. 查看Linux系统软硬件信息
  5. 2012传统行业转型年:整合拓展互联网发展渠道
  6. 【渝粤教育】广东开放大学 国际金融 形成性考核 (48)
  7. go中make、new和直接var的区别
  8. UI设计素材模板|首页解析
  9. 奇异值分解(SVD)原理
  10. 2021年4月12日 关于VRRP!!!
  11. LeetCode 781. 森林中的兔子
  12. 抖音短视频账号运营方案
  13. 雷电2接口_USB、Type-C、雷电3都是怎么一回事?
  14. python中row是什么意思_Python中的2D列表(row total/grand total)
  15. 转本结束暑假2022.6.29-7.13我的深圳之行(体验)
  16. 30位90后霸榜! 福布斯: 比你年轻、比你有颜、比你有才华, 就是他们了!
  17. Unity 3D学习之路
  18. 7 张图带你搞懂二层和三层交换机之间的区别
  19. 数据透视:减半真的会导致币价上涨吗?
  20. 伪解决Selenium中调用PhantomJS无法模拟点击(click)操作

热门文章

  1. 在win10运行DOS环境与debug
  2. Excel VBA判断工作薄是否已经打开/判断Excel文件是否已经打开
  3. arduino ide+esp32-cam基于点灯科技blinker实现手机监控
  4. 《操作系统》第六章习题加解析(重点学习)
  5. WIN7下开启802.1x----MD5验证【转】
  6. 9适应之力加多少攻击_lol应之力进攻适应之力灵活是什么意思
  7. MySQL case when 用法 (转载)
  8. 一个字符训练材料生成的小文件
  9. ipad iphone开发_如何在iPhone,iPad或Mac上进行FaceTime通话
  10. linux上机复习题(部分答案)