静态库和动态库的制作使用与区别

本文详细介绍了静态库和动态库的概念、命名方式、链接时间和优缺点。静态库在编译时被整合进可执行文件,运行效率高但占用内存。动态库在运行时才链接,节省内存但可能需要额外的链接操作。制作和使用方法也进行了说明,包括解决动态库运行时找不到的问题。总结来说,静态库与动态库各有优势,取决于应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.什么是静态库

静态库是指在应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库。

1.1命名方式:

静态库的文件名命名方式是“libxxx.a”,库名前面加“lib”,windows和linux下后缀都用的是“.a”,“xxx”为静态库名。

1.2链接时间:

编译过程中被载入程序

1.3连接方式:

静态库的链接是将整个函数库的所有数据都整合进了目标代码。

1.4 优缺点:

·点:这样做的一个优点就是可执行程序可以直接运行,不再需要外部函数库的支持,因为所有函数都已经被编进去了。运行效率较高。

·缺点:假如多个程序使用同一个静态库,等同于多段相同的代码分别保存在不同的可执行程序中,变相占用了更多的内存空间。而且如果所使用的静态库发生更新改变,你的程序必须重新编译。

2.什么是动态库

动态库就是编译程序时,可执行程序中只保存对应的函数的引用表,只有到程序执行时,再链接对应的库。

2.1命名方式:

动态库的命名方式与静态库类似,前缀相同为“lib”,linux下后缀名为“.so(shared object)”即libxxx.so;而windows 下后缀名为“.dll(dynamic link library)”即libxxx.dll.

2.2链接时间和方式:

动态库在编译的时候并没有被编译进目标代码,而是当你的程序执行到相关函数时才调用该函数库里的相应函数。

2.3 优缺点:

·优点:多个可执行程序共用同一个库,节省内存。且动态库的改变并不影响 你的程序,所以动态函数库升级比较方便。

·缺点:因为函数库并没有整合进程序,所以程序的运行环境必须提供相应的库,运行可执行程序需要额外做一次链接操作,执行速度会相对慢一些。

3.使用方法

  • -o: 指定编译生成可执行文件名
  • -I:指定头文件的路径(这里是大写i)
  • -l:指定所需链接库的库名(这里是L的小写)
  • -L:指定链接所需要的库所在的路径
  • -static:静态链接

 

程序演示:

 

main.c

 13 #include<stdio.h>
 14 #include "test.h"
 15 int main(int argc ,char **argv)
 16 {
 17     printf("sum = %d\n",sum(4,6));
 18     printf("avg= %d\n",avg(4,6));
 19     return 0;
 20 }
sum.c

int sum (int a,int b)
{
        return a+b;
}

avg.c

int avg(int a,int b)
{
        return (a+b)/2;
}
test.h

#ifndef _TEST_H_
#define _TEST_H_
extern int sum(int a,int b);
extern int avg(int a,int b);

#endif

3.1制作静态库

gcc -c avg.c sum.c
ar -crs libstatic.a avg.o sum.o

3.2制作动态库

gcc -fpic -shared sum.c avg.c -o libshared.so

运行时往往会出现这样的报错 ,那么这是为什么呢?

 

原因是:Linux下在运行程序时,会默认到 /lib、/lib64、/usr/libLD_LIBRARY_PATH环境变量指定的路径下查找所需的动态库下查找所需的动态库文件,如果没有则抛错。而这时libshared.so并不在系统库路径下,所以会出错。我总结了以下四种解决方法:

(1)将所需要的libshared.so文件拷贝到/usr/lib路径下,当然这需要root权限。

(2)使用export命令在LD_LIBRARY_PATH环境变量中添加该动态库所在的路径,注意该命令只是临时生效,环境变量都是临时生效的,重启后失效。另外指定的路径必须是绝对路径;(用pwd命令查看绝对命令)。

(3) 可以用vim ~/.bashrc将路径加进shell配置文件里 source ~/.bashrc 生效命令或者重启都可以。因为每次启动用户账号,该用户的shell配置文件都会重新运行一次,所以使用该方法不用每次都设置。

(3) 在编译时添加 -Wl,-rpath,/your/lib/path/ (-Wl,-R /your/lib/path/)

在gcc中使用ld链接选项时,需要在选项前面加上前缀-Wl(小写L), -R(或-rpath)指定程序运行时库的路径。注意: 这个方法优点是不需要更改环境变量或者拷贝动态库到系统路径下, 它的缺点是只要更改了动态库, 那么就需要重新编译(就这一点而言类似于静态库)。

//对于本例子:
gcc main.c -o test -Wl,-R(运行时库的路径) -lshared -L库的路径 -I头文件路径

4.二者的区别总结

前面对于静态库动态库的介绍已经说明了两者的区别,在此归纳为以下三点:

生成可执行文件大小、可执行文件执行速度、库生效方式

总结而言:静态库牺牲了空间效率,换取了时间效率;动态库牺牲了时间效率,换取了空间效率。没有好坏区别,只看具体需要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值