动态库和静态库
区分以下四个概念:
静态库:程序在编译链接时候把库的代码链接到可执行代码中,程序运行时将不再需要静态库。
动态库:程序在运行时才去链接动态库的代码,多个程序可共享使用库的代码。
静态链接:即在链接阶段,将源文件中用到的库函数与汇编生成的目标文件.o合并生成可执行文件。通常具有内存扩大,但具有可移植性。
动态链接:l动态链接所调用的库函数代码并没有拷贝到程序的可执行文件中。它仅仅在exe文件中加入了调用的函数所在库文件和调用函数在文件中的位置等信息链接进目标程序,仅当应用程序被装入内存开始运行时,才从库中寻找相应函数代码,因此需要相应动态库文件的支持。
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省空间。
生成静态库
首先自己创建四份代码,add.h, sub.h, add.c, sub.c
在.h里写该函数的声明,在对应.c文件里写关于该函数的实现。
接下来一个main.c文件里,使用该函数。
代码如下:
=============add.h==================
#pragma once
int add(int x, int y);
=============add.c==================
#include "add.h"
int add(int x,int y)
{
return x + y;
}
=============sub.h==================
#pragma once
int sub(int x, int y);
==============sub.c=================
#include "sub.h"
int sub(int x,int y)
{
return x - y;
}
===============main.c================
#include <stdio.h>
#include "add.h"
#include "sub.h"
int main()
{
int a=20;
int b=10;
printf("add:20+10=%d\n",add(a,b));
printf("sub:20-10=%d\n",sub(a,b));
return 0;
}
首先链接.o文件。生成add.o和sub.o文件。
接下来生成静态库并查看静态库的目录信息:
使用的命令:
- ar是gnu归档工具。
- rc表示replace and create
- t:列出静态库中的文件
- v:详细信息
然后编译链接。
Linux下规定所有的库命名必须以lib开头,.a或.s。o为后缀,但实际该库的名字应该是不加前缀不加后缀
- -L:指定该库路径。
- -l:指定库名。
运行该可执行文件,结果正确。
但是我们知道静态链接是将代码拷一份给我的程序。所以按理说此时如果没有该库文件,可执行文件也可以正常运行。我们来试试。
显然,是符合我们的猜测的。说明了静态链接是将库里的代码拷一份给我的可执行文件的。
可以再观察下大小的差异。
可执行文件的大小要比.c文件大得多。
生成动态库
还是上面的代码直接拷来用。
首先生成动态库。
- shared:表示生成共享库格式
fPIC:产生位置无关码(不是很理解)
此时动态库已经生成。
接下来我们尝试使用
可以看到错误提示,在加载动态库时出错,找不到该动态库文件。
这里提供一种方法。
首先将该动态库文件拷贝至系统共享库路径下,一般指/usr/lib下。
更改LD_LIBRARY_PATH
这时运行就成功了。
再用ldd命令:记录应用程序所依赖的动态库。