静态库和动态库

									什么是库文件
									
1. 库文件是计算机上的一类文件,可以简单的把库文件看成一种代码的仓库,它提供给使用者一些可以直接拿来用的变量,函数或者类。
2. 库是一种特殊的程序,编写库的程序和编写一般的程序区别不大,只是库不能单独运行。
3. 库文件有两种:静态库和动态库(共享库),区别是:静态库在程序的链接阶段被复制到了程序中;动态库在链接的阶段没有被复制到程序中,
4. 而是程序在运行时由系统动态加载到内存中供程序调用。
5. 库的好处:1.代码保密,2.方便部署和分发
									静态库的制作
6. 命名规则
7. Linux:  libxxx.a
	lib: 前缀(固定)
	xxx: 库的名字
	.a : 后缀(固定)
  windows: libxxx.lib
  
8. 静态库的制作	
	(1) gcc获得.o文件
			gcc -c *.c
	(2).o文件打包,使用ar工具。(archive)
		ar rcs libxxx.a xxx.o xxx.o
			r - 将文件插入备存文件
			c - 建立备存文件
			s - 索引
			
	制作的静态库一般只要.o文件,不包含头文件.h。因为在每个.c函数里面都包含了头文件。

	例如现在有的源文件有下面所示图中的src里面的.c文件:
	制作静态库的过程为:
		ar rcs libcalc.a *.o
	通过上述的命令,生成了calc的静态库。复制到lib文件夹里面去。
									静态库的使用
9. 假设现在有下面的一些文件:
10.include文件夹是包含的是这些src函数的函数声明以及一些其他声明; lib文件夹包含的是这些src文件夹下面的原代码形成的静态文件
库;src文件夹里面就是一些源代码了;

在这里插入图片描述
//head.h里面的代码
在这里插入图片描述
//main函数的内容
在这里插入图片描述

12.通过命令成成可执行文件:
		(1). gcc main.c -o app;
	这时候会出现下面的错误信息:
		main.c:2:18: fatal error: head.h: No such file or directory;
	出现上述的信息是因为一般寻找头文件.h是在1当前文件夹下面,而我目前的main函数的位置和head.h的位置是不一样的。
	为了解决这个问题,引入了【gcc -I 文件夹】命令的使用。-I是指定头文件处在的位置的。
	
		(2). gcc main.c -I ./include -o app
	这时候出现了以下的错误信息:
		/tmp/ccUnTREq.o: In function `main':
		main.c:(.text+0x38): undefined reference to `add'
		main.c:(.text+0x58): undefined reference to `subtract'
		main.c:(.text+0x78): undefined reference to `multiply'
		main.c:(.text+0x98): undefined reference to `divide'
		collect2: error: ld returned 1 exit status
	这是因为上面指定了头文件中的函数没有找到,这时候就需要指定库文件了,通过 【-l 库名字】的方式加载库文件。
	
		(3. gcc main.c -I ./include -l calc -o app
	然而这时候出现了以下的错误信息:
		usr/bin/ld: cannot find -lcalc
		collect2: error: ld returned 1 exit status
	是找不到这个库的所处的位置,这时候就需要通过【-L 库的路径】来指定库的路劲;
	
		(4. 	gcc main.c -I ./include -l calc -L ./lib -o app
	这时候就生成了可执行文件app了;
		
		 	.
			├── app
			├── include
			│   └── head.h
			├── lib
			│   └── libcalc.a
			├── main.c
			└── src
			    ├── add.c
			    ├── div.c
			    ├── mult.c
			    └── sub.c

											动态库的制作
1. 命名规则:
2. 		Linux: libxxx.so
3. 			lib: 前缀(固定)
4. 			xxx: 库的名字,自己起
5. 			.so: 后缀(固定)		
6. 		windows: libxxx.dll


7. 动态库的制作:
8. 		gcc 得到.o文件,得到和位置无关的代码
9. 			gcc -c -fpic/-fPIC a.c b.c
10.		得到动态库
11.			gcc -shared a.o b.o -o libcalc.so 
12.			
											动态库的使用
13. 整个的文件树如下所示:
					.
					├── app
					├── include
					│   └── head.h
					├── lib
					│   └── libcalc.so
					├── main.c
					└── src
					    ├── add.c
					    ├── div.c
					    ├── mult.c
					    └── sub.c
14. 通过命令 gcc main.c -o app -I ./include/ -l calc -L ./lib 生成了可执行文件app;
15. 在执行./app的时候出现了如下的错误信息:
16. 	./app: error while loading shared libraries: libcalc.so: cannot open shared object file: 
17. 																		No such file or directory
18. 上面的意思就是在执行app文件的时候无法打开下载共享库文件libcalc.so。
19. 这就需要了解其工作原理了。
												工作原理
20. 静态库:GCC链接时,会把静态库中的代码打包到可执行程序中。
21. 动态库:GCC进行链接时,不会把动态库中的代码打包到可执行程序中。意思就是在进行链接的时候,需要将动态库加载进来才行。
22. 程序启动之后,动态库会被动态加载到内存中,通过ldd(list dynamic dependencies)命令检查动态库依赖关系。
23. 例如:ldd app
24. 		[root@localhost library]# ldd app
			linux-vdso.so.1 =>  (0x00007ffdbbcaa000)
			libcalc.so => not found(没找到)
			libc.so.6 => /lib64/libc.so.6 (0x00007f8b525fd000)
			/lib64/ld-linux-x86-64.so.2 (0x00007f8b529cb000)

25. 如何定位共享文件库呢?
26. 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。
27. 对于elf格式的可执行程序,是由ld-1inux.so来完成的,它先后搜索e1f文件的DT_RPATH段一>
28. 环境变量LD_LIBRARY_PATH -> /etc/1d.so.cache文件列表 -> /1ib//usr/lib目录找到库文件后将其载入内存。
											解决动态库路径的问题

30.1)在LD_LIBRARY_PATH添加库的路劲:
31. 		export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/牛客/lesson6/library/lib
32. 上面的命令中:后面的就是我们添加的路径。但是这是在终端中进行配置,关掉终端之后就没了。所以就需要永久性质的添加库文件的路径。
33. 有两种方式的配置:用户级别的配置和系统级别的配置。
34. 	a):用户级别的配置就是在用户级别的家目录下的.bashrc文件里面最后一行新添加上面的export命令;添加完之后进行source .bashrc
35. 	b):系统级别的话也可以在家目录下的.bashrc文件中添加动态库路径;也可以在/etc/profile文件中添加。
36. 
37.2) 修改/etc/ld.so.cache文件列表
38. 	打开/etc	/ld.so.cache文件是我们看不懂的乱码二进制状态,我们不能直接修改它,需要间接修改它,所以直接打
39./etc/ld.so.conf文件,直接在后面添加库的路径。
39.
40.3)其他的方法不建议使用

在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值