linux程序设计第四版
库:预先编译好的方法/函数的集合
.c文件编译成.o文件,再将.o文件的方法放入库文件
存放库文件的标准路径 /usr/lib 用户安装的 /lib 系统本身的
所有的头文件.h存放在 usr/include
命令在 /usr/bin /bin
比如:
list.h 声明
list.c 实现 编译生成 list.o 链接到main里面 每个人使用都要list.c文件编译 如果多次就会重复多次
静态库命名规则 : libmylist.a 共享库:liblist.so
.查看程序使用了哪些共享库 ldd main(main为程序名字)
使用库的意义
省去了每一次编译的过程,提高了程序生成的速度,避免重复做无用的事情
隐藏我们自己代码的实现,对代码形成一种保护
静态库
静态库的创建与使用
add.c
#include "my.h"
int add(int x,int y)
{
return x+y;
}
max.c
#include "my.h"
int max(int x ,int y)
{
return x>y ? x:y;
}
my.h
int max(int x,int y);
int add(int x,int y);
main.c
#include<stdio.h>
#include<stdlib.h>
#include"my.h"
int main()
{
int a = 3;
int b = 2;
printf("add=%d\n",add(a,b));
printf("max=%d\n",max(a,b));
exit(0);
}
libxx.a lib为前缀 .a为扩展名
1.所有.c文件编译成.o文件
2.打包做出库,ar crv libxx.a *.o
ar是建立或修改备存文件的命令,参数c表示建立备存文件,r表示插入备存文件,v表示显示执行过程。
共享库 libxx.so 《程序员自我修养》第八章
1.将所有.c文件编译成.o文件
2.生成共享库 gcc -shared -fPIC -o libmyfoo.so *.o/*.c
参数的意义《C专家编程》
shared的意义
-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行
使用库
gcc -o main main.c -L路径 -l库名
没有指定库,编译会失败,要加路径和库名 路径在标准目录下不用加 在当前位置要加 -L路径 -l库名
执行可执行程序时还会调用库文件(共享库特点),因此有两种办法 改变环境变量LD_LIBRARY_PATH,将路径为本地路径,可以系统会在本地路径搜索共享库,或者直接吧共享库放入标准库文件目录下
系统的头文件一般放在/usr/include 系统的库文件一般放在/usr/lib /lib 可执行程序 /usr/bin /bin
环境变量 LD_LIBRARY_PATH : 系统搜索标准库文件的路径 可在一个终端中指定搜索路径,指定程序运行时链接共享库的位置
终端关闭后失效,临时改变LD_LIBRARY_PATH=. ( . 为当前位置 ,中间不能有空格,此时LD_LIBRARY_PATH为本地变量,可通过 echo $LD_LIBRARY_PATH 查看)
export LD_LIBRARY_PATH ( 将LD_LIBRARY_PATH 设为环境变量)
共享库与静态库的区别
静态库 里面的方法会编译链接包含到程序 体积太大
共享库 编译链接,只做标记 没有包含方法的实现 运行程序时 动态加载(速度较慢),并且里面方法可以被多个程序共享使用
静态库是在生成可执行程序时,将静态库的方法包含在了可执行程序中,即删除静态库,但由于静态库方法已经被包含在了可执行程序中,则程序仍可执行,不再依赖于外部静态库。
共享库是在运行程序时才动态加载库方法,若删除共享库,则程序运行时进行动态加载库方法时找不见共享库,程序将无法执行。
静态库的运行速度快,但程序体积相对较大,不易版本升级,若升级,则程序需要重新编译;
共享库由于运行要动态加载库文件,则运行速度慢,但程序体积小,方便版本升级,程序不用重新编译
问题
- 使用什么命令可以查看某个进程使用了哪些库
使用ldd main命令
- 制作共享库时,-fPIC含义是什么
表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,所以动态载入时是通过代码拷贝的方式来满足不同的调用,而不能达到真正的代码段共享的目的
关于gcc的编译参数:
-fPIC 生成与位置无关的代码,这样库就可以在任何位置被连接和装载
-shared 代表共享库
-o 链接生成指定名字的库或程序
-l 指定要链接的共享库
-L 指定共享库所在路径