跟我学c++中级篇——Linux下的静态库之一

28 篇文章 3 订阅

 

一、静态库

动态库学习完成后,要学习静态库了。其实,静态库的出现要比动态库要早,毕竟静态库相对动态库来说,从重用的角度来看,可以最先被设计人员想到,早期的静态库,其实就是多个编译单元的简单组合,它完全可以像普通的拼插玩具一样直接拼插到别的软件中,而不需要这个依赖那个依赖。
换句话说,静态库是一个完整的软件模块的描述和运行的集合。既然是完整的,就会有一个现象,那么静态库是可逆向的,或者说,静态库是一系列目标文件的集合的文件。
静态库和动态库的区别在于:
1、静态库是完整的模块,可执行文件直接加载即可使用,而动态库需要进行库目标寻找,动态加载,但是要考虑动态库的依赖关系。
2、静态库链接时只导入必要的符号,而不会加载整个静态库,不过,随着链接的越多,可执行文件会越来越大;动态库链接则需要整体导入,其在链接过程时可执行文件并不会变大(或者说变化非常小),但在运行时,会变大。
在实际情况中,会有这么一种场景,可执行文件需要一个动态库来加载一个静态库,而根据上面的分析,发现二者是互相矛盾的,如何解决这类问题呢?这个在链接器中使用 --whole-archive即可。它表示,无论可执行文件是否需要库中的符号,链接器都要无条件链接之后的N个库。
其它如安卓等都类似的链接符号。

二、创建静态库

在Linux创建静态库非常简单,至少比动态库要简单。创建静态库需要两个步骤:
假设有a.cpp,b.cpp(c文件类似)
1、生成.o文件
g++ -c a.cpp b.cpp
执行完成后在当前目录生成了a.o b.o两个目标文件。
2、使用ar命令打包
ar -rcs libstatictest.a a.o b.o
执行完成后在当前目录会生成libstatictest.a这个静态文件,如果感兴趣可以把这个文件用解压文件解压开,会发现其实就是两个目标文件。
ar命令是一个打包命令,其常用的几个参数意义为:
r:在当前库中插入或者替换模块。
c:创建库,有就替换没有创建。
s:创建目标索引,加快创建库的时间,大S表示不创建。
v:表示显示详细信息,时间、大小等
t:显示库中的具体的文件名称。
其它可参考ar的具体的命令细节。

三、应用

代码走一波:

//add.h
int Add(int a,int b);
//add.cpp
#include <iostream>
#include "add.h"

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

//mul.h
int Mul(int a,int b);
//mul.cpp
#include <iostream>
#include "mul.h"

int Mul(int a,int b)
{
        return a*b;
}
//main.cpp
#include <iostream>
#include "add.h"
#include "mul.h"

int main()
{
        int a = Add(1,2);
        int b = Mul(2,3);
        std::cout<<"Add result:"<<a<<" Mul result:"<< b<<std::endl;
}

编译运行结果:

g++ -c add.cpp mul.cpp
ar -rcs libstest.a add.o mul.o
g++ -o ms main.cpp -L. -lstest      ---说明:-o要保持在-lstest前面

Add result:3 Mul result:6

有没有什么问题?对,不像动态库一样需要设置路径,运行时和编译链接时的都得设置,这里只要编译通过了,运行时就可以使用,这也验证了上面的代码膨胀的过程,也就是说,这个库是完整的,不需要在运行时再去寻找加载。

四、总结

在实际工程中,怎么把握使用静态库和动态库呢?这个没有具体的强制性的条目。一般来说,如果库的数量少,想提供给多个支持部门,对可执行文件膨胀大小不太敏感,客户技术水平比较差等情况下,都可以使用静态库。不过,动态库或者说共享库更能体现库的优势,根据实际情况把握就可以了。
在实际工程中,麻烦的在于中间商,要面对各种不同编译情况的动态库,静态库,而且不断的嵌套调用(动态库调动态库,动态库调静态库,依次…),出现的各种离奇的编译链接和运行错误会让程序员崩溃再崩溃。但只要把握好了两者的具体的由来,那么在处理实际问题时,会有一个清晰的思路,指引着解决问题的方向,再根据实际经验不断的调试,就一定能解决大部分问题(有些问题是无法解决的,比如库本身的问题,对方不提供源码且没有支持)。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值