动态库和静态库

Posted younger-zhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态库和静态库相关的知识,希望对你有一定的参考价值。

1. 概念介绍

我理解的库分为数据库和程序库,一般来说库是被调用的,不可以单独执行。

数据库也包括对数据的操作部分,但是主要围绕数据;

程序库就是提供接口、专门实现某些功能的函数。

 

程序库(函数库)分为静态库和动态库。

前者在链接的时候加入到执行代码中,链接之后可以删除,不会影响程序执行;

后者在链接时只是指定了库的位置,不会加入代码中,程序执行前删除动态库会出问题。

 

动态库的优点:

  • 是代码(什么意思???)
  • 易于模块更新,更新库时源程序不需要重新编译
  • 节省大量空间!

 

 

2. 静态库的生成和使用

①编译

g++ -c print_hello.cpp print_world.cpp

把源文件cpp编译成多个.o静态库,可以一次编译多个;
使用gcc或者g++,默认生成的.o文件就是静态库

②打包

ar csrv libprint_helloworld.a print_hello.o  print_world.o

ar可集合许多文件成为单一的备存文件,所有成员文件皆保有原来的属性与权限;
该命令将目标文件1~n加入到指定的静态库中。如果该静态库不存在,则创建静态库文件。
静态库.a文件,是一些.o目标文件的集合,有.o生成.a的过程,其实就是一个打包

  • 参数r:把列表中的目标文件加入到静态库中
  • 参数c:若指定的静态库不存在,则创建该库文件
  • 参数s:更新静态库文件的索引,是指包含新加入的目标文件的内容

③链接

g++ -o main main.cpp -L./ -lprint_helloworld

注意这里的格式:
a. -L紧跟着路径
b. -l+静态库名,不要后缀.a
使用.a静态库链接成可执行文件,链接之后可以删除所有的.o和.a静态库文件;
静态库在程序链接的时候使用,连接器会将程序中使用到的函数的代码从库文件拷贝到可执行文件中
一旦链接完成,在程序执行的时候就不需要静态库了。

 

 

3. 动态库的生成和使用

①生成.o静态库:

g++ -c -fPIC print_hello.cpp print_world.cpp

②制作动态库
g++ -shared  -o libprint_helloworld.so print_hello.cpp print_world.cpp
-fPIC用于生成与位置无关的代码,-shared用于将位置无关的代码制作成动态库。

③链接

g++ -o main main.cpp -L. -lprint_helloworld

上面的一些规则,比如.so文件的开头是lib,-L后面紧跟着路径,-l后面+动态库但是不加后缀……都是为了保证这一步链接可以顺利完成!

假如这一步链接随意一点:g++ -o main main.cpp print_helloworld.so,那么上面的规则都不需要!

④添加进库/usr/lib/

上面完成之后,直接执行:.main会出错——找不到库文件。

还需要把共享库添加进合适的位置: sudo cp print_helloworld.so /usr/lib/

因为虽然链接的是当前目录的libprint_helloworld.so,但是执行的时候确实从共享库文件夹里面寻找

我猜这样做的机制,是为了鼓励人们把共享库放到大家都可以够得着的地方。

 

 

4. 直接编译+链接
链接的时候不一定使用库文件,还可以直接使用cpp文件!
g++ -o main main.cpp print_hello.cpp print_world.cpp

默认是先编译生成静态库.o,然后再进行链接,链接完毕之后删除.o文件。

 

 

参考链接:

https://my.oschina.net/daowuming/blog/775068

https://www.cnblogs.com/li-hao/archive/2012/03/01/2376227.html

 

以上是关于动态库和静态库的主要内容,如果未能解决你的问题,请参考以下文章

C语言里面的动态库和静态库

动态库和静态库的区别

Linux下的静态库和动态库

CMake 学习四:CMake 构建静态库和动态库

Linux下的动态库和静态库详解

CGO静态库和动态库