静态库和动态库创建与区别

来源:互联网 发布:常用办公软件有哪些 编辑:程序博客网 时间:2024/06/05 03:33

一、静态库

    静态库以.a为后缀,程序在编译链接的时候把库的代码链接到可执行文件中,程序运行的时候就不再需要静态库.

    首先我们拿最简单的加法函数为例,这个时候我们首先需要创建add.c add.h .c main.c三个源文件

add.c

#include"add.h"int add(int x, int y){    return x+y;}

add.h

#ifndef __ADD_H__#define __ADD_H__int add(int x,int y);#endif//__ADD_H__

main.c

#include<stdio.h>#include"add.h"int main(){    int ret = add(10,20);    printf("add(10,20)=%d\n",ret);    return 0;}

当这三个源文件创建完毕后我们开始来写Makefile,这是静态库最核心的部分,我们先给出源代码,接下来进行解释

main:main.c libadd.agcc main.c -L . -ladd -o mainlibadd.a:gcc -c add.c -o add.oar -rc libadd.a add.o.PHONY:cleanrm -rf main libadd.a add.o

   我们首先需要将add.c 进行到汇编阶段生成目标文件,记住到这一步是-c选项,不要混淆,有了目标文件后,我们接下来开始进行生成静态库,ar它是一个GNU工具归档工具,rc选项代表( Replace  and Create),生成的库的文件名必须是libxxx.a这样的形式,这样我们在链接库的时候,可以直接用 -lxxx 这样的形式,即当告诉编译器-lxxx时,编译器就会在指定目录搜索libxxx.a或者libxxx.so,当做完了这些之后,最后一步就是将静态库和main.c链接起来生成可执行文件,在这里 -L选项代表 指定库路径,-l则代表库名,我们可以发现当最后成功生成可执行文件main后,删除静态库,不影响最终的结果,这也验证了静态库链接到可执行文件后,运行时候就不再需要静态库。


二、动态库

        动态库以.so为后缀,程序在运行的时候才去链接动态库的代码,多个程序可以共享使用库的代码.我们来同上面一样,做一个测试,就能更加深刻的理解动态库是怎么一回事。

        动态库,和上面的只有在写Makefile时候不一样,我们同样先将代码奉上,接下来进行解释

main:main.c libadd.sogcc main.c -L . -ladd -o mainlibadd.so:gcc -fPIC -c add.cgcc -shared -o libadd.so add.o.PHONY:cleanclean:rm -rf  main libadd.so


       -fPIC用来产生位置无关码, 这是动态库需要的特性,gcc -fPIC -c add.c 执行完后会生成add.o,-shared表示生成动态库, 同样是将add.o变成动态库文件,最后再次将动态库和main.c链接生成可执行文件main,注意如果该路径下同时存在libadd.a 和libadd.so,则会优先链接libadd.so,即同时存在同名的动态库和静态库,gcc会优先链接动态库,

  在动态库这里,我第一运行./main,发现会报错,这个的原因原来是Linux是通过/etc/ld.so.cache文件搜寻要链接的动态库的,而/etc/ld.so.cacheIdconfig读取/etc/ld.so.conf文件生成的。如果我们把libadd.so所在路径添加到/etc/ld.so.conf中,再以root权限运行ldconfig程序,更新/etc/ld.so.conf,./main运行时候就可以找到libadd.so,但还有一种更简单的办法,如果我们只是为了感受下动态库,那就是为main指定LD_LIBRARY_PATH,我们在shell下输入LD_LIBRARY_PATH=. ./main,(注意是两个点),这时候我们就会发现已经成功执行。LD_LIBRARY_PATH的作用就是告诉main现在当前路径下寻找链接的动态库



三、区别

      1.一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件(add.o)的整个机器码

  2.在可执行文件开始运行前,外部函数的机器码由操作系统从磁盘上的该动态库复制到内存,这个过程称做动态连接

  3.动态库可以在多个程序间共享内存,所以可执行文件很小,节省了磁盘空间,操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到的该库的进程所共享,节省了内存和磁盘空间






阅读全文
0 0
原创粉丝点击