Linux 静态库动态库制作和使用

在这里插入图片描述

自己的理解:遵循了程序员的模块编程思想

:为了对功能的增删更方便
:为了查改错误更方便
:版权

百度百科:定义

一般是指编译器提供的可在c源程序中调用的函数。可分为两类,一类是c语言标准规定的库函数,一类是编译器特定的库函数。
由于版权原因,库函数的源代码一般是不可见的,但在头文件中你可以看到它对外的接口。

Linux c语言分文件编程编程演示

方法一:把主函数和被调函数分开

		   编译的时候gcc calculate.c calculateH.c   两个文件一起编译
		   编译器会有警告,甚至结果会出错

分开前

operation.c


#include <stdio.h>
int addition(int a,int b)
{
	return a + b;
}
int subtraction(int a,int b)
{
	return a - b;
}
int multiplication(int a,int b)
{
	return a * b;
}
float divide(int a,int b)
{
	return (float)a / b;
}
int main ()
{
	int a;
	int b;	
	int result;
	float resultfloat;
	printf("请输入两个数\n");
	printf ("数一:");
	scanf("%d",&a);
	printf ("数二:");
	scanf("%d",&b);
	result = addition(a,b);
	printf("%d+%d=%d\n",a,b,result);
	result = subtraction(a,b);
	printf("%d-%d=%d\n",a,b,result);
	result = multiplication(a,b);
	printf("%d*%d=%d\n",a,b,result);
	resultfloat = divide(a,b);
	printf("%d/%d=%f\n",a,b,resultfloat);
	system("pause");
	return 0;
}

分开后

calculateH.c


int addition(int a,int b)
{
	return a + b;
}
int subtraction(int a,int b)
{
	return a - b;
}
int multiplication(int a,int b)
{
	return a * b;
}
float divide(int a,int b)
{
	return (float)a / b;
}

calumniate.c

#include <stdio.h>
int main ()
{
	int a;
	int b;	
	int result;
	float resultfloat;
	printf("请输入两个数\n");
	printf ("数一:");
	scanf("%d",&a);
	printf ("数二:");
	scanf("%d",&b);
	result = addition(a,b);
	printf("%d+%d=%d\n",a,b,result);
	result = subtraction(a,b);
	printf("%d-%d=%d\n",a,b,result);
	result = multiplication(a,b);
	printf("%d*%d=%d\n",a,b,result);
	resultfloat = divide(a,b);
	printf("%d/%d=%f\n",a,b,resultfloat);
	system("pause");
	return 0;
}

编译:gcc calculate.c calculateH.c
两个文件一起编译
会有警告(warning)

方法二 :多添加自制头文件

加多一个头文件calculate.h 里面是calculateH.c函数声明


int addition(int a,int b); 
int subtraction(int a,int b); 
int multiplication(int a,int b); 
float divide(int a,int b); 
                           

calculate.c添加头文件


#include "calculate.h"

为什么是" "号而不是<>:
<>:默认去/usr/include/或者/usr/local/include/找头文件
“ ” :会先从当前目录找头文件,找不到再到默认路径找,再找不到就报错

编译指令还是:gcc calculate.c calculateH.c
没有警告,运行结果正确。

静态库

静态函数库:在执行前(编译时)就加入到目标程序中。
优点:1、静态库已经在编译时打包到运用程序加载快,
2、发布的时候程序无需提供静态库,因为已经编译在app(application)中,移植方便。
缺点:1、链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。
2、更新、部署、发布麻烦。

制作静态库

1、原材料:xxx.c 或 xxx.cpp
将c文件生成 .o
指令:gcc a.c b.c -c :运行该指令就会生成 a.o 和 b.o 文件
也可以gcc calculateH.c -c :只生成calculateH.
2、原料:xxx.o
ar rcs 静态库名字,原料
ar rcs libtest.a a.o b.o :打包两个只生成一个libtest.a
或者ar rcs libtest.a a.o :只打包a.o生成libtest.a
文件名前面lib三个字母一定要有!!!

	r、c、s、分别是什么含义
	可以直接在命令行输入:ar
	r[ab][f][u]  - replace existing or insert new file(s) into the archive  :替换现有文件或将新文件插入存档(主要)
	 [c]          - do not warn if the library had to be created  :如果必须创建库,不警告
	 [s]          - create an archive index (cf. ranlib)  :创建存档索引

使用静态库编译:ar rcs calculate.a calculateH.o
gcc calculate.c -lcalculate -L ./ :出错
这里的-L:编译时从-L指定的路径去找库,gcc默认地从/usr/local/lib, /usr/lib中搜索库文件

调试

	1.  objdump -a calculate.a  :查看静态文件适用于哪种系统(多少位)
	查询结果:没发现毛病
In archive calculate.a:

calculateH.o:     file format elf64-x86-64
rw-r--r-- 0/0   1584 Dec 31 16:00 1969 calculateH.o

2. 试着编译gcc calculate.c calculate.a    :结果编译成功
加上路径也成功gcc calculate.c /home/abc/xxx/calculate.a

  1. [root@Xecho mycode]# gcc -o 2 2.c /usr/lib/libm.a
    [root@Xecho mycode]#
    它告知gcc:在编译2.c时,加入位于/usr/lib中的libm.a库(C数学库)。C库文件默位
    于/usr/lib, /usr/local/lib系统目录中; gcc默认地从/usr/local/lib, /usr/lib中搜索库文件
    指定库文件的绝对路径比较麻烦,有一种简化方法:
    [root@Xecho mycode]# gcc -o 2 2.c -lm
    看到这里终于想起编译时可以砍头去尾:但是头尾一定要有,ar rcs calculate.a calculateH.o 忘记添加lib

动态库

动态库比静态库更常用

动态函数库:是在程序执行时动态(临时)由目标程序调用。

优缺点跟静态库相反。
优点:程序小,简洁,多程序可共用,节省内存,更新动态库,不用重新编译可执行文件
缺点:运行慢,发布需要提供动态库

制作动态库

1、gcc calculateH.c -c -fpic :生成calculateH.o文件
-fpic :用于编译阶段生成目标文件就得使用,用来生成位置无关码

PIC,全称Position Independent Code
位置无关码:位置无关代码是指代码无论被加载到哪个地址上都可以正常执行。

2、gcc -shared calculateH.o -o libcalculate.so :生成so文件
-shared :指定生成动态库

或者一步到位
gcc -shared -fpic calculateH.c -o libcalculates.so :直接生成so文件

!!!注意 .so 文件名必须以 lib 开头

使用动态库编译:gcc calculate.c -lcalculates -L ./ calculates
运行calculates 的时候发现会报错

./calculates: error while loading shared libraries: libcalculates.so: cannot open
 shared object file: No such file or directory

原因是:可执行程序运行时才去调用动态库,默认地会从/usr/lib/文件夹下面找

解决方法:

	1、可以把动态库libcalculates.so拷贝到/usr/lib/下面
		但是不建议:因为这样会使/usr/lib/更乱
	2、 暂时配置环境变量:export  LD_LIBRARY_PATH=/home/hgs/learningDocument
	只适用于当前窗口
	3、写一个shell脚本:
		a.创建 vi start.sh
 	 1 export LD_LIBRARY_PATH=/home/hgs/learningDocument
 	 2 ./calculates
		b.给start.sh 可执行权限 sudo chmod +x start.sh 

	4、修改环境变量
		a. 打开环境变量配置文件sudo vi ~/.bashrc
		b.在文件末尾添加export LD_LIBRARY_PATH=/home/hgs/learningDocument
		c.使配置文件生效source ~/.bashrc

最后:运行结果

abc@ubuntu:~/learningDocument$ ./calculates 
请输入两个数
数一:4
数二:5
4+5=9
4-5=-1
4*5=20
4/5=0.800000

动态函数库和共享函数库是一个东西

共享函数库的命名规则
libxxx.so.0.1.2 :

lib:代表共享库
xxx:库名  
so:共享库固定后缀  
0:版本号 
1:次版本号 
2 :发行版本号
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值