gcc生成与使用静态库.a与动态库.so

前言

上一篇文章中,我们已经了解到使用gcc编译程序的基本过程,本文将在Linux环境下使用gcc生成.a静态库与.so动态库。下面案例可供参考。


1 .a静态库与.so动态库的生成与使用

将一些公用函数制作生成函数库以便供其他程序使用。这些函数库分为静态库动态库两种。

1.1 初识静态库与动态库

1.1.1 静态库

之所以称为静态库,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接

静态库的特点:

  • 静态库对函数库的链接是放在编译时期完成的
  • 程序在运行时与函数库再无瓜葛,便于移植
  • 所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件,浪费空间和资源

1.1.2 动态库

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题

动态库的特点

  • 把对一些库函数的链接载入推迟到程序运行的时期
  • 可以实现进程之间的资源共享
  • 做到链接载入完全由程序员在程序代码中控制

1.2 hello实例

1.2.1 文件准备

  1. hello程序

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;
}
  1. gcc编译生成.o文件
gcc -c hello.c

在这里插入图片描述

1.2.2 静态库使用

  1. 创建静态库

使用工具:ar
命名规范:静态库的命名是以lib为前缀,紧接着跟静态库名,扩展名为.a

ar -crv libmyhello.a hello.o

在这里插入图片描述

  1. 程序中使用静态库

(1)

gcc -o hello main.c -L. -lmyhello

注意:对于自定义的静态库,main.c还可以放在-L.-lmyhello之间,否则myhello没有定义。

-L.:表示连接的库在当前目录

在这里插入图片描述

(2)

gcc main.c libmyhello.a -o hello

在这里插入图片描述

(3)先生成main.o,再生成可执行文件

main.o gcc -c main.c
gcc -o hello main.c libmyhello.a

在这里插入图片描述

  1. 验证静态库的特点

删除静态库

rm libmyhello.a

在这里插入图片描述

由此可以看出,在删除静态库的情况下,运行可执行文件,程序仍旧正常运行,这表明静态库与程序执行没有联系,同时,表明静态库在程序编译的时候是被链接到代码中的。

1.2.3 动态库的使用

  1. 创建动态库

工具:gcc
命名规范:动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀lib,但文件扩展名为.so

gcc -shared -fPIC -o libmyhello.so hello.o

在这里插入图片描述

shared:表示指定生成动态链接库,不可省略
-fPIC:表示编译为位置独立的代码,不可省略
命令中的-o一定不能够被省略

  1. 在程序中执行动态库
gcc -o hello main.c -L. -lmyhello
或 gcc main.c libmyhello.so -o hello

在这里插入图片描述
执行时会发现出现错误,由于运行时是在/usr/lib中找库文件的,所以需要将libmyhello.so复制到目录/usr/lib中,问题即解决。

2 实例运用

详细步骤见hello,下文将不做详细解说

2.1 文件准备

  • main.c
#include<stdio.h>
#include"sub.h"
void main()
{
	int a,b;
	printf("Please input the value of a:");
	scanf("%d",&a);
	printf("Please input the value of b:");
	scanf("%d",&b);
	printf("a+b=%.2f\n",x2x(a,b));
	printf("a/b=%.2f\n",x2y(a,b));
}
  • sub1.c
float x2x(int a,int b)
{
	float c=0;
	c=a+b;
	return c;
}
  • sub2.c
float x2y(int a,int b)
{
	float c=0;
	c=a/b;
	return c;
}
  • sub.h
#ifndef SUB_H
#define SUB_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif
  • 生成.o文件
gcc -c sub1.c sub2.c

在这里插入图片描述

2.2 静态库与main函数的链接

在这里插入图片描述
此时文件大小如下:
在这里插入图片描述

2.3 动态库与main函数的链接

在这里插入图片描述
此时文件大小:
在这里插入图片描述

2.4 对比

静态库
在这里插入图片描述

动态库

在这里插入图片描述
通过比较发现静态库要比动态库要小很多,生成的可执行文件大小也存在较小的差别。


总结

通过几个程序用gcc生成静态库和动态库的练习过程,基本上能够熟练的生成静态库和动态库。静态库和动态库存在是为了将除主函数外的其他函数放在库里,以便其他程序也可以使用。而学会使用静态库与动态库,极大的方便我们的程序实现。

参考资料

  1. 动态库和静态库
  2. Linux ar命令(更改静态库相关属性信息)
  3. 用gcc生成静态库和动态库
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日常脱发的小迈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值