静态库和动态库的操作和使用

一.库

 链接静态库是将库中的被调用代码复制到调用模块中。
 链接共享库则只是在调用模块中,嵌入被调用代码在库中的(相对)地址。
 静态库占用空间非常大,不易修改但执行效率高。
 共享库占用空间小,易于修改但执行效率略低。

二.函数的定义

add.h

#ifndef _ADD_H__
#define _ADD_H__
int add(int,int);
#endif //_ADD_H__

add.c

#include "add.h"
int add(int a,int b){
	return a+b;	
}

minus.h

#ifndef _MINUS_H__
#define _MINUS_H__
int minus(int,int);
#endif //_MINUS_H__

minus.c

#include "minus.h"
int minus(int a,int b){
	return a-b;	
}

div.h

#ifndef _DIV_H__
#define _DIV_H__
int div(int,int);
#endif //_DIV_H__

div.c

#include "div.h"
int div(int a,int b){
	return a/b;	
}

main.c

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

三.静态库

	1.创建静态库
		(1) 编辑源程序:.c/.h  		gcc -c  xxx.c  检查语法错误
			把所有的.c文件进行编译不链接处理   生成.o文件
		(2) 编译成目标文件:ar -r liboper.a *.o
		(3) 打包成静态库文件:ar -r lib+静态库名字
			ar指令:ar [选项] 静态库文件名 目标文件列表 
			-r - 将目标文件插入到静态库中,已存在则更新 
			-q - 将目标文件追加到静态库尾 
			-d - 从静态库中删除目标文件 
			-t - 列表显示静态库中的目标文件 
			-x - 将静态库展开为目标文件 
	 
	 2.使用静态库  在.c文件中使用静态库中的函数  需要包含头文件
			gcc -I 头文件的路径 main.c -l+静态库名 -L.静态库存储的路径
			在相同目录时直接调用  gcc main.c liboper.a 
			-I 查找头文件的路径
			-l 链接静态库/动态库
			-L 查找静态库/动态库的路径
			

VirtualBox:~/unix/staticlib$ gcc -c add.c div.c minus.c
VirtualBox:~/unix/staticlib$ ar -r liboper.a *.o
ar: creating liboper.a
VirtualBox:~/unix/staticlib$ gcc main.c liboper.a 
VirtualBox:~/unix/staticlib$ ./a.out
30
10
2

四.动态库

	1.创建动态库
	(1.c .h编译
	(2)gcc -c -fpic xxx.c   编译所有的.c文件
	(3)gcc -shared *.o -o liboper.so   
		 gcc -shared -fpic *.c -o lib动态库名.so
	2.使用动态库
	 (1)编写代码 包含头文件 使用动态库中的函数
	 (2)gcc -I 头文件路径 main.c -l动态库名 -L动态库路径
	 (3)链接动态库即使生成了可执行文件 该文件依然不能运行
 		export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./unix/staticlib
		除了和静态库的使用方法一样以外  多了LD_LIBRARY_PATH

VirtualBox:~/unix/staticlib$ gcc -c -fpic *.c
VirtualBox:~/unix/staticlib$ gcc -shared *.o -o liboper1.so
//VirtualBox:~/unix/staticlib$ gcc -shared -fpic *.c -o liboper.so
VirtualBox:~/unix/staticlib$ gcc -I main.c  liboper.so -L.
VirtualBox:~/unix/staticlib$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./unix/staticlib

加载动态库

#include <stdio.h>
#include <dlfcn.h>
typedef int (*FUNC)(int,int);
int main(){
	void *handle = dlopen("liboper1.so",RTLD_NOW);
	if(handle == NULL){
		printf("%s\n",dlerror());//获取错误信息
		return -1;
	}
	FUNC f1,f2,f3,f4;	
	f1 = dlsym(handle,"add");//根据标识符获取该标识符在动态库中的相对地址
	if(f1 == NULL){
		printf("%s\n",dlerror());
		return -1;
	}
	int ret = f1(888,999);
	printf("ret = %d\n",ret);
	f2 = dlsym(handle,"minus");
	ret = f2(888,999);
	printf("ret = %d\n",ret);
	f3 = dlsym(handle,"div");
	ret = f3(888,999);
	printf("ret = %d\n",ret);
	dlclose(handle);
	return 0;	
}

VirtualBox:~/unix/staticlib$ gcc loadsharedlib -ldl

五.静态库和动态库的区别

1.生成静态库和动态库的步骤不一样
	静态库  ar -r lib静态库名.a  *.o
	动态库  gcc -shared *.o -o lib动态库名.so
2.静态库文件没有 ‘x’权限 动态库有  -x 指定源代码的语言
3.链接静态库时 是把调用函数的指令用静态库中的二进制代码替换
	链接动态库时 是直接在函数调用处嵌入函数在动态库中的相对地址
	使用静态库生成的可执行程序比较大   把静态库的数据拷贝到可执行文件
	使用动态库生成的可执行程序比较小 
4.链接静态库 编译时 比较慢 执行效率高
	链接动态库 编译时 比较快 执行效率低
5.链接静态库 生成的执行文件在运行过程中不依赖于静态库文件
  链接动态库 生成的执行文件依赖于动态库
	LD_LIBRARY_PATH 链接动态库生成的可执行程序在运行时查找动态库的路径
6.静态库本质上是对目标文件进行打包				
	动态库其实是对目标文件进行进一步的编译,是可以执行的二进制指令
	如果xxx.a 和 xxx.so都有
	gcc -I . main.c -loper -L . 链接的是动态库
	gcc -I -static main.c -loper -L .

如果在开发过程中 有一个.c文件被修改 需要编译哪些动态库
1.c文件所在的动态库
2.连接了该动态库的所有动态库和可执行程序都需要重新编译  -ldd
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值