
扫描二维码
获取更多精彩
嵌入式杂牌军

编辑|追梦星空
公众号|嵌入式杂牌军
也行努力从来都不是无心插柳柳成荫的。
文 章 导 读
今天给小伙伴们介绍了下Linux中的静态链接库与动态链接库,介绍了它们的定义,生成等内容,今天主要带大家有一个整体的认识,后面会结合实例将这两种库用起来!
阅读过程中如果有什么问题,可以后台留言哈,!
1 Linux函数库分类
根据链接方式的不同函数库可以分为静态链接库和动态链接库。
1)静态链接库
通过静态链接方式生成的库称为静态链接库。
静态链接时几个程序调用的相同的程序都要与被调用程序结合起来。
例如:程序段P1和P2都要调用程序段P,静态链接之后,P1和P结合在一起,P2和P也结合到了一起,P程序段不具有共享性。
上面提到的结合,可以理解为将两个程序片段编译到一起。
静态链接,加参数-static,后面进行命令使用说明。
2)动态链接库
通过动态链接方式生成的库称为动态链接库。
程序链接默认为动态链接。
动态链接是当多个程序段调用同一程序时,第一次调用时,被调用的程序段会被加载到内容,如果有其他程序再次条用,其他程序段使用的就是前面内存备份的那段程序段,即动态链接使用时程序段被加载到内存,且具有共享性(共用性)。
例如:程序段P1和P2都要调用程序段P,P1先执行,调用到了P,此时系统将P加载到内存,P2运行时,也会使用内存中的P。
3)动态链接与静态链接的差别
① 链接方式不同。
程序默认链接方式为动态链接,静态链接需要在命令中加入-static参数。
② 占用空间大小不同。
今天链接每次调用相同的程序段,都要将调用的程序段编译到代码中,所以它占用的空间相对比较大。
动态链接有共用性,它占据的空间相对小些。
2 函数库的存放目录及后缀
1)函数库的存放目录
在linux系统中,动态链接库和静态链接库主要存放在/lib和/usr/lib两个目录下。
2)动态链接库与静态链接库的后缀
静态链接库的后缀为*.a。
动态链接库的后缀为*.so、*.so.*(比如*.so.6)。
3 创建静态链接库与动态链接库
所用代码是前面文章中的代码,在此再贴一下。
#include<stdio.h>
#include<stdlib.h>
// 全局变量(函数之外的变量)
int GlobalInitVar = 0x12; //全局的,初始化的变量:数据段
int GlobalUninitVar; //全局的,未初始化的变量:数据段
static int StaticGlobalInitVar = 0x34; //全局的,静态的,初始化的变量:数据段
static int StaticGlobalUninitVar; //全局的,静态的,未初始化的变量:数据段
const int ConstGlobalVar = 0x56; //全局的,常量
int main()
{
// 局部变量
int LocalInitVar = 0x01; //局部的,初始化的变量:栈
int LocalUninitVar; //局部的,未初始化的变量:栈
static int StaticLocalInitVar = 0x02;//局部的,静态的,初始化的变量:数据段
static int StaticLocalUninitVar; //局部的,静态的,未初始化的变量:数据段
const int ConstLocalVar = 0x04; //局部的,栈
int *pMalloc;
pMalloc = malloc(sizeof(int)); //通过malloc分配得到的局部:堆
printf("\nGlobalInitVar = %p,GlobalInitVar = 0x%x\n", &GlobalInitVar, GlobalInitVar);
printf("GlobalUninitVar = %p,GlobalUninitVar = 0x%x\n\n", &GlobalUninitVar, GlobalUninitVar);
printf("StaticGlobalInitVar = %p,StaticGlobalInitVar = 0x%x\n", &StaticGlobalInitVar, StaticGlobalInitVar);
printf("StaticGlobalUninitVar = %p,StaticGlobalUninitVar = 0x%x\n\n", &StaticGlobalUninitVar, StaticGlobalUninitVar);
printf("ConstGlobalVar = %p,ConstGlobalVar = 0x%x\n", &ConstGlobalVar, ConstGlobalVar);
printf("ConstLocalVar = %p,ConstLocalVar = 0x%x\n\n", &ConstLocalVar, ConstLocalVar);
printf("LocalInitVar = %p,LocalInitVar = 0x%x\n", &LocalInitVar, LocalInitVar);
printf("LocalUninitVar = %p,LocalUninitVar = 0x%x\n\n", &LocalUninitVar, LocalUninitVar);
printf("StaticLocalInitVar = %p,StaticLocalInitVar = 0x%x\n", &StaticLocalInitVar, StaticLocalInitVar);
printf("StaticLocalUninitVar = %p,StaticLocalUninitVar = 0x%x\n\n", &StaticLocalUninitVar, StaticLocalUninitVar);
}
Linux下的运行结果。
1)静态链接方式
需要安装glibc的rpm包,我的Linux比较老,是Linux 6,对应的rpm安装命令如下。
rpm -ivh glibc-static-2.12-1.80.el6.i686.rpm
或者将包拷备到Linux系统中,双击安装即可。
静态链接命令如下。
gcc -static VarAddrTest.c -o VarAddrTest
2)动态链接方式
动态链接命令换掉-static即可。
gcc -c VarAddrTest.c -o VarAddrTest
可以看出静态链接的方式生成的目标文件要比动态链接的方式的大得多。
通过readelf -d 可以查看编译所用到的动态链接库。
可以看到用到了libc.so.6这个动态库。
3)两种链接库的生成
生成动态链接库。
生成静态链接库。
后面用到静态链接或动态链接库再给大家讲解它们的使用吧!
今天就到这吧,希望对小伙伴有所帮助哈,喜欢的话欢迎转发、点赞、分享、在看、转载哈,。
