UNIX,linux动态库和静态库学习总结

新接触的一块知识,相对来说比较陌生。听的时候觉得不难,可是自己真的动手去做的时候,有很多的地方需要注意,同时也需要理解。

关于环境变量老师讲的不多,我能理解多少就总结多少了。

首先从shell说起,shell是用户与操作系统(内核)的接口,对于内核来说程序同样是用户,这里的用户不能仅理解为使用者。至于为什么有shell这个东西,目前的理解是因为系统内核的安全系数比较高,不能让用户轻易触碰到。而shell在ubuntu操作系统下叫做bash。

下面说环境变量,操作系统会为每一个进程创建一个环境变量表,而这个环境变量表,会根据进程之间的关系,具有可继承的属性(只针对全局变量,局部变量不可继承)。这个环境变量表里记载了很多有用的信息,但对环境变量表的使用,还需要时间慢慢加深。

对于shell 和 环境变量表了解的不深就不多说了,下面说一下静态库和动态库的问题。

首先,在实际工作中我们绝大多数情况下会使用动态库,因为其维护起来更为容易,而易维护这一点我想是很多公司比较看重的(个人观点),而且如果使用静态库程序的体量也会变的更大,综合下来恐怕只有极少数的情况会用到静态库。

关于静态库和动态库的学习,我认为比较重要的一个先决条件是对编译的过程比较了解,这样能更好的理解链接和程序执行的过程,当然在调用动态库的时候还会涉及到指针,基础永远是最重要的,基础多牢,决定着未来楼能建多高。

在这里就顺便复习一下编译的过程,编译过程从大的层面来说是3步,讲细致一点是4步 ,具体如下,

第一步:预处理,代码如下

gcc -E test.c -o test.i  代码的作用是讲test.c 文件通过预处理生成目标文件test.i , 在预处理过程主要完成的事情:1,将头文件里的内容完全复制过来  2,完成宏替换

第二步:编译 代码如下

gcc -S test.i   这一步是将预处理之后的文件test.i 翻译成汇编文件,结果存储在test.s 中

第三步:汇编 代码如下

gcc -c test.s 这一步是汇编文件test.s 翻译成二进制文件,结果存在test.o 中

第四步:链接 代码如下

gcc test.c 这段代码会直接将我们的 .o 文件与所需要的库链接起来,最终生成可执行文件

注:其实gcc test.c 这个命令是将上面三步全部包含在内并且加上链接这一步,这样就直接生成可执行程序了。

以上,是较为详细的步骤,一般也可分为三步,预处理,编译(包括编译和汇编两步),链接。

这个过程还是比较重要的,每位同学都应该了解。

这个过程了解了,那关于静态库和动态库理解起来就不是很难。

比如我们有5个文件add.c  add.h  sub.c  sub.h  main.c  ,这五个文件分别是加法函数,加法函数头文件,减法函数,减法函数头文件,主函数。

具体细节就不说了,说一下基本流程。静态库就是将 add.c 和 sub.c 生成的目标文件 add.o 和 sub.o 打包起来放到一个文件 libmath.a(静态库的命名规则不多说) 里,这个libmath.a就是我们说的静态库。最后将 主函数的源文件和静态库一起编译即可,最后生成的可执行文件是将 主函数中调用的函数进行了替换,也就是说编译完成后,不再需要libmath.a文件,程序依旧可以运行。静态库函数的优点是运行速度较快,说到这里,其实如果能够对底层cpu的处理过程有些了解会更好。

静态库说完了,说一下动态库。

制作动态库的过程就不多说了,除了命令不太一样,过程基本差不多,最终是将add.o 和 sub.o 打包到 libmath.so 文件。打包到动态函数库 然后和主函数源文件一起编译,这个过程没有问题,生成可执行文件就可以运行了。

但是,这样存在的问题是,程序一执行,动态库就会和可执行文件一起加载到内存中,而动态库的函数不一定会被一直调用,所以可能导致的情况就是动态库可能大多数时候都仅仅是占用内存,而没有被调用。为了避免出现这样的情况,于是出现的动态加载的实现方法,简而言之就是什么时候需要使用库函数什么时候将库函数调入内存,用完了再将其从内存中删除。

这样c 语言就给我们提供了相对应的函数以实现动态加载。涉及到的几个主要命令如下

其中,dlopen 是将动态库加载到内存中,dlsym 是找到你需要用的函数 dlclose

是库函数用之后,将其释放。我这里为什么要说成是释放呢?其实我想这个过程有点像malloc 的过程,dlopen 返回的是动态库被加载到内存的地址,但是因为这个库是共享的,不可能因为你一个程序不用了,就将其从内从中删除。所以此时dlopen返回的地址应该是相对地址,这样程序能够通过dlopen访问动态库,而且通过dlclose 也只是关闭了自己的通道,这个过程有点像free 掉 malloc 的空间,这个你可能需要稍微琢磨一下,这也同样是个人观点,但我觉得是有迹可循的,因为地址指针那一套都是比较相似的。

说的有点多了,暂时就总结到这里,我觉得同学们还可以再注意一点,静态库是需要和主函数源文件同时编译的,而动态库则不需要,这也是一个区别。

以上,如有不当之处,请多多指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值