GCC学习(动态库与静态库.a与.so)

一、GCC生成动态库和静态库

静态库.a与.so库文件的生成

概念 我们通常把一些公用函数制作成函数库,供其它程序使用。函数库分为静态库和动态库两种。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。

1.编辑生成例子程序

代码如下
hello.h

#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif //HELLO_H

hello.c

#include <stdio.h>
void hello(const char *name)
{
printf("Hello %s!\n", name);
}

main.c

#include "hello.h"
int main()
{
hello("everyone");
return 0;
}

2.生成并使用静态库

gcc编译得到.o文件,再创建并使用静态库
在这里插入图片描述
我这里存在一处报错的原因是因为有一个文件我之前命名过,这里覆盖失败,重新写一下就好了。
解释部分命令

#gcc main.c libmyhello.a -o hello //连接
#rm libmyhello.a                 // 移除
./hello                         //查看、验证

3.生成并使用动态库

先创建动态库,再执行动态库
注意 会出现两个错误,一个是因为文件运行时在usr/lib中寻找库文件,一个是因为没有执行权限。
按照我的操作步骤执行即可
在这里插入图片描述

4.动态库静态库比较

在上面的过程中不难发现,即使移除了静态库,程序仍然可以运行,但是动态库却是程序运行所必需的。
那么,当静态库与动态库同名时,程序会优先使用哪一个呢?
执行以下步骤:
①删除. h .c 以外的所有文件
②建立同名动态库和静态库
③执行比较
通过执行可发现,会出现动态库所需要的步骤,可见,程序会优先使用动态库。

二、.a与.so的生成和使用

1.静态库.a的生成和使用

创建四个文件,代码如下

//A1.C
#include<stdio.h>
void print1(int arg)
{
	printf("A1 print arg:%d\n",arg);
}

//A2.c
#include<stdio.h>
void print2(char *arg)
{
	printf("A2 printf arg:%s\n",arg);
}

//A.h
#ifndef A_H
#define A_H
void print1(int);
void print2(char *);
#endif

//test.c
#include<stdio.h>
#include"A.h"
int main()
{
	print1(1);
	print2("test");
	exit(0);
}

具体操作如下
在这里插入图片描述

2.共享库.so的生成和使用

在这里插入图片描述
在这里插入图片描述
共享库文件大小
在这里插入图片描述

3.文件大小对比

通过以上的实验不难发现静态库比动态库小许多,但是文件使用时,会优先使用动态库

三、自建函数静态库.a 与.so 库文件

目标
①使用main函数代码调用x2x和x2y ;将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小。
②将x2x、x2y目标文件用 ar工具生成1个 .so 动态库文件, 然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序,记录文件的大小,并与之前做对比。

1.编写函数

编写以下四个函数
x2x.c

#include<stdio.h>
float f1(int a,int b){
float i;
i=a+b;
printf("This is x2x.c!\n");
return i;
}

x2y.c

#include<stdio.h>
float f2(int a,int b){
float i;
i=a*b;
printf("This is x2x.c!\n");
return i;
}

x.h

#ifndef x_H 
#define x_H
float f1(int,int);
float f2(int,int);
#endif      

main.c

#include<stdio.h>
#include"x.h"
int main(){
        int a=2,b=3;
        float m,n;
        m=f1(a,b);
        printf("%f\n",m);
        n=f2(a,b);
        printf("%f\n",n);
        return 0;
}

在这里插入图片描述

2.静态库.a 文件的生成与使用

具体的创建步骤上面已经有了介绍,这里不做赘述
①文件生成过程
在这里插入图片描述
②运行结果及文件大小
在这里插入图片描述

3.共享库.so 文件的生成与使用

①文件生成过程
同样的,遇到报错使用管理员权限转移文件
在这里插入图片描述
②执行结果及文件大小
在这里插入图片描述

4.文件大小对比

通过比较两个文件大小可以发现,动态库比静态库大许多。在这里附上一个关于动静态库对比的链接动静态库对比

四、总结

通过这一篇的学习,我更加熟练了gcc的常用命令,学会了解决动态库生成过程中无法汇编的方法,对于什么是动态库,什么是静态库有了更加清晰的认识与了解。掌握了自己汇编生成动态库和静态库的方法。
参考链接gcc生成静态库.a和动态库.so


版权声明:本文为weixin_54089068原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。