静态库和动态库的区别和制作


文章目录

  • 静态库和动态库的区别和制作
  • 一、什么库 为什么要使用库
  • 二、静态库
  • 如何使用静态库:
  • 三、动态库(共享库)
  • 如何使用共享库:
  • 环境变量作用
  • 静态库和共享库的优缺点:


一、什么库 为什么要使用库

库:指的是代码的仓库,可以看作是代码的压缩包(.o文件的集合)。
例如我们使用一些代码库时,不需要得到源代码就可以调用(但需要有头文件),既可以保密、隐藏细节,又方便使用。

二、静态库

静态库:编译时直接把库中的目标文件,拷贝到可执行文件中。

创建静态库的过程:
1、编译源代码:.c/.h

我己经写好了我的工具函数文件tool.c tool.h

2、编译出目标文件:gcc -c code.c -> code.o

将我的tool.c编译出目标文件tool.o

3、打包出静态库:ar -r libname.a code1.o code2.o …

再运行代码ar -r libtool.a tool.o,此时提示:ar: creating libtool.a静态库libtool.a就制作完成了(静态库.a,动态库.so

如何使用静态库:

在使用静态库时会用到几个参数:-L, -l(小写L), -I(大写i)
-L:是库文件的目录
-l(小写L):需要链接的文件(不需要全名比如libtool.a只需-ltool即可)
-I(大写i):)是 Include 头文件路径
方法一:直接参与编译,调用都和库文件在同一目录下。 此时-L,-l的路径都默认是当前目录路径

gcc math.c libtool.a   //math.c是调用者

2、添加参数-L库的路径 -l库的名字可以活力lib和.a。

gcc math.c -I(/头文件路径) -L(/库文件路径) -ltool

比如我制作的库函数调用时:gcc math.c -I/home/myj/zhizhen/DIYtool -L/home/myj/zhizhen/DIYtool -ltool

3、设置LIBRARY_PATH,然后配置-l,一次配置长期有效
你会发现每次都要在参数后加路径这是一件非常麻烦的事情,所以就可以用到方法三,配置环境变量。
用终端打开~/.bashrc文件,在末尾添加代码export LIBRARY_PATH=$LIBRARY_PATH:/home/myj/zhizhen/DIYtool 环境变量LIBRARY_PATH后加的是你库文件所在的路径。然后保存关闭,系统之后的就会先到该目录下寻找库文件执行,一次配置长期有效。

三、动态库(共享库)

共享库(动态库):编译时只验证库中的语法是否正确、函数是否能正确调用,而不拷贝,当可执行文件运行,需要用到库中的功能时,再跳转到共享库中执行(共享库是跟可执行文件一起加载执行的)。

创建共享库的过程:

1、编写源代码:.c/.h(步骤和静态库相同)
2、编译出目标文件:gcc -c code.c -> code.o(步骤和静态库相同生成.o文件)
3、打包生成共享库:gcc -shared code1.o code2.o … libname.so

gcc -shared tool.o libtool.so
如何使用共享库:

1、直接参与编译,调用都和库文件在同一目录下。

gcc math.c libtool.so(只是为了检查语法)。

2、添加参数-L库的路径 -l库的名字可以活力lib和.so。

gcc math.c -I(路径) -L(路径) -ltool

3、设置LIBRARY_PATH,然后配置-l,一次配置长期有效。
用终端打开~/.bashrc文件,在末尾添加代码export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/myj/zhizhen/DIYtool 环境变量LD_LIBRARY_PATH后加的是你动态库文件所在的路径。然后保存关闭,系统之后的就会先到该目录下寻找库文件执行,一次配置长期有效。

如果共享库和静态库都存在,优先加载共享库,如果确实想加载静态库可以在编译时添加-static参数。

环境变量作用

LIBRARY_PATH 指定编译时加载共享库、静态库的路径
LD_LIBRARY_PATH 指定共享库运行时的加载路径

静态库和共享库的优缺点:

静态库是将库被调用的代码复制到可执行执行文件中,共享库是把要调用的代码的在共享的位置记录在可执行文件中,当执行程序时候,调用到
共享库中的代码时再跳转过去执行被调用的代码(共享库可以看作是没有入口的可执行程序,因此必须要有执行权限)。
    由于静态库中的代码是直接拷贝到可执行文件中,因此运行速度快。而使用共享库中的代码当程序运行时还需要跳转到共享库中执行,因此运行速度慢。
如果库中的代码有更新,使用静态库的可执行程序必须重新编译,而使用共享库的可执行程序则不需要更改(更新程序方便)。