3动态库与静态库

目录

3.1动态库与静态库的概念与区别

3.2库的使用

3.3自定义静态库的创建与使用

3.4自定义动态库的创建与使用

3.1动态库与静态库的概念与区别

概念

在写C语言程序的时候,都知道要包含头文件,才能使用printf、scanf等库函数,为什么没有实现这些函数就可以使用呢?

C语言程序的编译过程熟知的四个步骤:预处理、编译、汇编、链接。经过前面三个步骤形成的目标文件(二进制文件)需要经过最后一步链接形参可执行文件。

本质上库就是一个目标文件,它里面包含了库函数的实现,最后和我们自己写的文件(包含系统的头文件)链接起来就可以使用库函数了,这样程序就可以正常执行了。

区别

Linux下常见的库有分为两种,静态函数库(简称静态库)和动态函数库(也称为共享函数库,简称动态库或共享库)。它们有什么区别呢? 动态库:

以.so结尾 命名规则: 例如 libxxxx.so 这个库, 库名是xxxx,库名前需要加lib,后缀为.so 特点: 动态库没有编译进可执行程序,而是程序运行时动态的申请调用使用到的函数, 优点:实现进程的资源共享,当程序在运行的时候需要调用某个动态链接库函数时候,OS会先查看所有正在运行的程序,看内存里面是否已经有此函数的拷贝了,有责共享那个拷贝,没有才会链接载入,这样会大大节省OS的内存资源; 升级容易,升级动态链接库即可,不需要重新编译可执行程序; 缺点:程序不可独立运行 静态库:

以.o结尾 命名规则: 和动态库类似,例如 libxxxx.o 这个库, 库名是xxxx,库名前需要加lib,后缀为.o 特点: 静态库的链接是将整个函数库的所有数据都整合进了目标代码,编译后的执行程序不在需要外部的函数库支持,可独立运行。 优点:编译后,可执行文件不需要外部支持; 缺点:生成的可执行程序大;静态库改变了,就需要重新编译可执行程序。 原文链接:Linux动静态库的创建和使用_s_persist的博客-CSDN博客_linux动态库和静态库的使用

3.2库的使用

默认情况下,gcc自动使用动态库

使用ldd命令可以查看它所依赖的库

3.3自定义静态库的创建与使用

3.3.1库包含三部分:

1、头文件.h,用来说明库中暴露出来的方法的使用

2、库文件本身, 即对应函数的实现编译为.o目标文件

3、说明文档,如何使用库

所以,制作一个简单的库只需要将.o文件打包,加上对应头文件即可使用。

3.3.2制作步骤:

1、将.c文件生成.o文件

举例:创建一个加法函数add.c和一个减法函数的文件,生成对应的.o文件

gcc -c add.c -o add.o

 

2、使用ar工具制作静态库

语法格式:ar rcs lib+自定义库名 添加的文件的.o文件

举例:将add.o和sub.o制作成库

ar rcs libmymath.a add.o sub.o

3、编译静态库到可执行文件

语法格式:gcc 文件.c lib库名 -o a.out

举例:创建test文件实现加法和减法

gcc test.c libmymath -o test

3.3.3静态库对应头文件

当我们编译test文件时加上-Wall表示显示所有警告

gcc test.c libmymath -o test -Wall

会这样报错:

即告诉隐式声明add函数,因为你没有声明,其自动隐式声明了该函数,但系统只会声明参数类型与返回值类型相同的类型,如

int func(int,int);

如果使用的函数并不满足参数类型与返回值类型相同的情况,就有可能出错。

可以在test的main函数前加上声明即可解决问题,但是当我们使用其他库时,往往不是我们自己定义的库,不知道它该如何声明。

但在真正使用库时也不需要声明,是因为其定义了自己的头文件。

同理,我们也要定义自己的库的头文件,来减少不必要的麻烦。

注:#ifndef _MYMATH_H

#define _MYMATH_H

#endif

是为了防止重复声明头文件而出错

最后测试

 

3.4自定义动态库的创建与使用

原理与静态库有部分类似。

3.4.1制作步骤

1、将.c文件生成.o文件(生成与位置无关的代码 -fPIC)

以add.c为例

gcc -c add.c -o add.o -fPIC

2、使用gcc -shared 制作动态库

语法格式:gcc -shared lib库名.so 文件.o

举例mymath

注:此处的add.o和sub.o和之前不同,为fPIC

gcc -shared -o libmymath.so add.o sub.o

3、编译可执行程序是,指定所使用的动态库。 -l:指定库名,-L指定库路径,-I指定头文件路径。

gcc test.c -o test -lmymath -L/root/test_c/d/ -I/root/test_c/d/

4、运行可执行程序 ./test

开始执行时会报错,是因为动态链接器工作时需要提供动态库所在目录位置,通过改变环境变量

export LD_LIBRARY_PATH=动态库所在目录。

注:链接器:工作于链接阶段,工作时需要 -l和-L,动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置。

但是当你关闭该终端,重新打开时,环境变量的配置会回到默认位置所以需要永久修改执行时的路径

5、永久修改动态链接器的环境变量

打开etc目录中的隐藏文件bash_profile

vim ~/.bash_profile
将路径加入export LD_LIBRARY_PATH=动态库所在目录。
如果不是第一次设置环境变量,则写
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库所在目录

运行

6、复制动态库文件到回去查询的目录

因为回去查找,所以不存在找不到的情况。

使用ldd命令查找test运行时会查找的目录

将文件复制到该目录下,记完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值