静态库与动态库
静态库文件后缀为.a 程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
动态库文件后缀为.so 程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码。
在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接。
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。
静态库与动态库的生成
都需要先将源码文件编译成自己的目标文件(动态库可以直接从源码生成),也就是从.c文件到.o文件。
最终这些.o文件链接在一起生成动态库还是静态库或者可执行程序,那取决于链接过程。
如果要生成的是一个库文件,那么这些代码中不能有main函数。
如果要生成的是一个可执行程序,那么这些代码中有且只有一个main函数。
静态库生成和使用:
1. 将所有的.o文件打包到一起生成。
ar -cr lib***.a ***.o
-c create创建
-r replace替换
2. 查看静态库中的目录列表:
ar -tv lib***.a
-t 列出静态库的文件
-v 详细信息
3. 链接静态库:
gcc ***.c -L. -l***(库名称,lib后面名称)
-L 指定库路径
-l 指定库名称
动态库生成和使用:
1. 将所有.c文件生成.o文件,需要加一个选项-fPIC
gcc -fPIC -c ***.c -o ***.o
-fPIC:产生位置无关代码。
2. 生成动态库:
gcc -shared -o lib***.so ***.o
-shared 表示生成动态库
3. 使用动态库:
gcc ***.o -o *** -L. -l***
-L 指定动态库路径
-l 指定动态库名 去掉lib
运行动态库
i. 动态库是一个运行时库,需要在程序运行的时候也加载到内存中,这个加载的过程是操作系统干的,会去指定位置加载动态库,因此我们需要将动态库放到指定位置才可以运行程序。
拷贝.so文件到系统共享路径下,一般指/user/lib,需要root权限。
mv lib***.so /usr/lib
ii. 更改LD_LIBRARY_PATH环境变量
export LD_LIBRARY_PATH=.
iii. 链接动态库
gcc ***.c -l***
在Linux下静态库和动态库的具体操作
add.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int a, int b);
#endif // __ADD_H__
add.c
#include "add.h"
int add(int a, int b)
{
return a + b;
}
sub.h
#ifndef __SUB_H__
#define __SUB_H__
int sub(int a, int b);
#endif // __SUB_H__
sub.c
#include "sub.h"
int sub(int a, int b)
{
return a - b;
}
main.c
#include<stdio.h>
#include"add.h"
#include"sub.h"
int main()
{
int a=10;
int b=20;
printf("add(%d,%d)=%d\n",a,b,add(a,b));
a=100;
b=20;
printf("sub(%d,%d)=%d\n",a,b,sub(a,b));
return 0;
}
静态库的操作:
动态库的操作
在指定路径下使用动态库
直接使用动态库: