首页 >> 大全

Linux中动静态库的生成与使用

2023-11-10 大全 24 作者:考证青年

0 定义

库可以看作是代码仓库,库里面封装了很多方法,当客户(也可以指程序员)需要使用时,可以直接导入库,然后调用库中的方法,可以很好的提高编程效率

1 动静态库的区别?

动静态库最大的区别除了体现在名字上(?)主要体现是在它们生成程序的链接阶段的时候。在链接阶段时,静态库会将自己的代码全部复制进程序中;而动态库则会进行分批加载

ps.linux中静态库的后缀名是.a 动态库的后缀名是.so

分批加载

在链接前,磁盘、地址空间、内存关系如下图所示:

​​​​​​此时,a.out被加载到内存上

1.链接时,也就是需要调用动态库时,动态库会先加载到内存上。

2.如果程序碰到了需要使用的库中的方法,内存中的那个方法就会建立与页表间的链接

3.此时代码会被加载到地址空间的共享区(栈与堆之间)里面

4.当代码区里面的代码需要调用方法时,就会到共享区中调用

ps.正是因为动态库中的文件是分批加载到共享区中的,所以如果多个程序使用这个库,那么他们可以共享库中的方法(都到一个地方去找),就不像静态库傻乎乎的全部复制到每一个程序代码中,更加节省空间。不过调用也会比静态库更慢,因为内存和地址空间之间需要建立映射关系,所以加载动态库的程序运行速度相对较慢。

结束了理论时间就来看看代码!

2 动静态库的链接(代码实操) 前期准备

首先我们先写个hello.c、math.c文件,准备把它编辑成库,代码如下:

linux静态库动态库_linux静态库的生成与使用_

并在它们的头文件中声明这两个函数(这边省略),我们在写一个含有main函数的main.c来调用它们:

#include "mymath.h"
#include "hello.h"int main()
{int x = 1;int y = 2;printf("x+y = %d\n",mymath(x,y));hello();return 0;
}

并把hello.c和.c生成为后缀为.o的目标文件

gcc -c hello.c  -o hello.o 
gcc -c mymath.c -o mymath.o

静态库的生成与使用

我们用ar(归档)来生成静态库:

     //lib+文件名.a  后面跟.o文件
ar -rc libmylib.a hello.o mymath.o

此时文件中就生成了一个.a的静态库文件

我们把头文件和库放进另一个文件夹中,并把打包前的原.c和.o文件放到别的地方去(虽然打完包后不需要,但是后面编译动态库还需要),我们来模拟一下使用库的情况:

那么我们该怎么使用静态库呢?

//-I 后面跟着头文件的路径
//-L 后面跟库的路径
//-l(小L)后面跟要使用的库名(不用加后缀也不用加前面的lib)
gcc main.c -o main -I ./a/include -L ./a/lib -lmylib

编译成功后是可以运行的:

系统路径下的头文件存放在:/usr/中

系统路径下的库文件存放在:/usr/lib64中

//到刚刚的include目录中,把.h文件复制进系统路径中
sudo cp *.h /usr/include//复制库到系统路径中
sudo cp *.a /usr/lib64

复制后,就可以直接编译main.c文件并执行(记得也要指定库名!)

linux静态库动态库__linux静态库的生成与使用

动态库的生成与使用

动态库的生成采用以下代码:

//fPIC 是告诉编译器要生成位置无关的代码 这是动态库的一个条件之一
//shared 告诉编译器生成的是.so动态库文件,而不是一个可执行文件的别名
gcc -fPIC -shared -o libmylib.so hello.c mymath.c

生成后,我们把动态库的库文件和头文件同样的放入其他的文件夹边:

如何使用动态库?

                                       //你自己存放库的地址
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zsy/class/io/ku/so/lib

然后我们就可以直接编译生成可执行程序了,不过还是要指定库名。生成后我们再使用ldd(列出动态依赖关系)命令查看该可执行程序的动态依赖关系,可以看出连接的是动态库

这个方法有不好的一点就是再次启动终端时就无法编译了,命令会重置,所以我们可以看看另一种方法

我们可以在路径/etc/ld.so.conf.d/里面创建自己的conf文件,并将库路径复制到里面,然后我们就可以永久使用了

//创建mylib.conf文件到/etc/ld.so.conf.d/中
sudo touch /etc/ld.so.conf.d/ mylib.conf

/ect/ld.so.conf.d中的文件:

然后我们 vim mylib.conf 把库所在路径复制进去(记得sudo!!)

然后我们就可以直接编译咯(当然还是要指定库名)

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了