Linux动态库与静态库

动静态库与链接方式

  • 静态库与动态库
    • 什么是静态库
    • 什么是动态库
  • 链接方式
    • 动态链接
    • 静态链接
    • 静态链接和动态链接的区别

静态库与动态库

我们写代码的时候,要使用官方提供的库文件,比如printf,scanf之类的,这些都是已经写好的库文件,不需要我们再去写,供我们使用,方便开发。
但是我们调用这些库的时候只有头文件而没有C文件,这是因为我们这些库函数是在链接的时候才加载到程序里面的。这些库文件是已经被编译好的二进制文件。

Linux中一种常以.a为后缀,为静态库;另一种以.so为后缀,为动态库。在Windows中静态库以.lib为后缀,动态库以.dll为后缀。

什么是静态库

可重定位目标文件以一种特定的方式打包成一个单独的文件,并且在链接生成可执行文件时,从这个单独的文件中“拷贝”它自己需要的内容到最终的可执行文件中。这个单独的文件,称为静态库。
我们生成可执行程序时,直接把静态库打包到我们可执行程序里面,这样就会使我们的可执行程序变大,因为所有的库函数都放到了可执行程序里面。

什么是动态库

动态库和静态库类似,但是它并不在链接时将需要的二进制代码都“拷贝”到可执行文件中,而是仅仅“拷贝”一些重定位和符号表信息,这些信息可以在程序运行时完成真正的链接过程。
说白了就是用到哪个函数找哪个函数,这样我们可执行程序的体积就会小一些

链接方式

动态链接

我们可以通过ldd查看我们的程序链接库,去掉前缀lib,去掉后缀.so.6,就是我们库的名字,发现是C,就是C语言的动态库。
Linux默认使用的是动态链接
Linux动态库与静态库_第1张图片

可以通过file命令来查看程序使用的链接方式,图中就是使用的动态链接
在这里插入图片描述

静态链接

我们的系统中默认没有静态库,如果要进行静态链接要下载静态库
没有静态库进行静态链接就会报下面的错误
进行静态链接的命令就是gcc -o newname 源文件 -static
在这里插入图片描述
下载静态库的命令,前面是C的静态库也可以顺便把后面C++的静态库下载下来
sudo yum install -y glibc-static libstdc++-staticLinux动态库与静态库_第2张图片
可以发现静态链接产生的文件非常大,就是把我们需要的库文件全部拷贝到了可执行程序里面

静态链接和动态链接的区别

运行方式不一样
静态库被使用目标代码最终和可执行文件在一起,而动态库与它相反,它的目标代码在运行时或者加载时链接。动态链接的程序,会把动态库加载到内存里面,但是只加载一份,很多程序可以共用。而静态链接只能自己用。如果两个程序的库一样,那么就会浪费内存

依赖性不一样
静态链接的可执行文件不需要依赖其他的内容即可运行,而动态链接的可执行文件必须依赖动态库的存在。所以如果你在安装一些软件的时候,提示某个动态库不存在的时候也就不奇怪了。所以静态库的跨平台性要好一些。

维护成本不一样
如果静态库中某个函数的实现变了,那么可执行文件必须重新编译,而对于动态链接生成的可执行文件,只需要更新动态库本身即可,不需要重新编译可执行文件。正因如此,使用动态库的程序方便升级和部署。

生成链接文件不一样
既然动态库和静态库所实现的功能都一样,为什么我们还要去下载静态库呢,直接拷贝动态库不就好了吗?比较动态库和静态库是在链接模式不同的时候区分的。
答:动态链接的处理要比静态链接要复杂,例如,如何在运行时确定地址?多个进程如何共享一个动态库?动态库里的地址不是绝对编制,是编的偏移量。二者形成链接文件的方式不同,所有还是不能直接拷贝,但是更深层次的问题就只能去阅读更专业的书籍才能解决了。

加载速度不一样
由于静态库在链接时就和可执行文件在一块了,而动态库在加载或者运行时才链接,因此,对于同样的程序,静态链接的要比动态链接加载更快。所以选择静态库还是动态库是空间和时间的考量。但是通常来说,牺牲这点性能来换取程序在空间上的节省和部署的灵活性时值得的。

你可能感兴趣的:(Linux,linux,编译器,链接)