Linux基础—” Linux静态动态库及相关编程“ 面试必问的知识点你了解了嘛

文章目录

  • Linux库引入之分文件编程
    • 分文件编程案例
  • Linux库
    • 1. 库是什么
    • 2. 静态函数库
    • 3. 动态库

Linux库概念及相关编程(面试重点)

Linux库引入之分文件编程

分文件编程案例

好处:分模块的编程思想

例如分文件编程,分3块

  • 网络 a

  • 超声波b

  • 电机c

    • a.功能责任划分
    • b.方便调试
    • c.主程序简洁

我们先来写一个简单的程序

#include 

int  add(int a,int b){	
	return  a + b;	
}
int  chu(int a,int b) {
	return  a / b;	
}
int  jian(int a, int b) {
	return a-b;
}
int  cheng(int a, int b) {
	return  a * b;	
}

int main()
{
	int data1;
	int data2;
	int ret;
	float retfloat;
	printf("请输入第一个数字\n");
	scanf("%d",&data1);
	printf("请输入第二个数字\n");
	scanf("%d",&data2);
	ret =add (data1,data2);
	printf("%d+%d=%d\n",data1,data2,ret);
	ret =jian (data1,data2);		
	printf("%d-%d=%d\n",data1,data2,ret);
	ret =cheng (data1,data2);                                    
	printf("%d*%d=%d\n",data1,data2,ret);
	ret =chu (data1,data2);                                    
	printf("%d/%d=%d\n",data1,data2,ret);
	return 0;
}

按分文件编程的话,
我们先按功能分为两个部分

功能模块(test2.c

int  add(int a,int b){	
	return  a + b;	
}
int  chu(int a,int b) {
	return  a / b;	
}
int  jian(int a, int b) {
	return a-b;
}
int  cheng(int a, int b) {
	return  a * b;	
}

主函数模块(test.c

#include
int main()
{
	int data1;
	int data2;
	int ret;
	float retfloat;
	printf("请输入第一个数字\n");
	scanf("%d",&data1);
	printf("请输入第二个数字\n");
	scanf("%d",&data2);
	ret =add (data1,data2);
	printf("%d+%d=%d\n",data1,data2,ret);
	ret =jian (data1,data2);		
	printf("%d-%d=%d\n",data1,data2,ret);
	ret =cheng (data1,data2);                                    
	printf("%d*%d=%d\n",data1,data2,ret);
	ret =chu (data1,data2);                                    
	printf("%d/%d=%d\n",data1,data2,ret);
	return 0;
}

这时候我们分文件了,如果开始编译,会出现什么效果呢?

gcc test.c test2.c

Linux基础—” Linux静态动态库及相关编程“ 面试必问的知识点你了解了嘛_第1张图片
我们在linux下是可以正常进行编译的。在树莓派中会提示警告 ⚠。
我们应当再把函数进行声明。

声明模块(test.h

int  add(int a,int b);
int  chu(int a,int b) ;
int  jian(int a, int b) ;
int  cheng(int a, int b) ;

我们在主函数中加入我头文件 #include"test.h"

主函数模块(test.c

#include
#include"demo.h"
int main()
{
	......
}

这样就可以在树莓派中无警告使用分文件编译了。

Linux库

1. 库是什么

库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容。

我们如何在Linux下创建自己的程序函数库

程序函数库可分为3种类型:

静态函数库(static libraries)
共享函数库(shared libraries)
动态加载函数库(dynamicallyloaded libraries)

1、静态函数库,是在程序执行前就加入到目标程序中去了,文件后缀是.a

2、动态函数库共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.so ,windows上叫动态加载函数库, 文件后缀是.dll

Linux中命名系统中共享库的规则
Linux基础—” Linux静态动态库及相关编程“ 面试必问的知识点你了解了嘛_第2张图片

2. 静态函数库

静态函数库是在程序执行前(编译)就加入到目标程序中去了

优点: 快

  1. 被打包到应用程序中运行速度快
  2. 发布程序无需提供静态库,因为已经在app中,移植方便

缺点:大

  1. 连接时候完整拷贝到可执行文件中,被多次使用就会有多份冗余拷贝,文件大。
  2. 更新,部署,发布麻烦

Linux基础—” Linux静态动态库及相关编程“ 面试必问的知识点你了解了嘛_第3张图片

命名规则
静态库文件名的命名方式是“libxxx.a”,库名前加”lib”,后缀用”.a”,“xxx”为静态库名。

制作步骤

原材料:源代码.c 或者 .cpp
有两步

  1. 将.c文件生成.o,gcc a.c b.c -c

  2. 将.o 打包
    ar rcs lib静态库的名字.a 原材料.o
    ar rcs libtest.a b.o

  1. 首先我们把功能程序 xxx.c 文件 gcc test2.c -c 生成 xxx.o文件:test2.o
    在这里插入图片描述
  2. 然后我们将xxx.o 打包, ar rcs libtext.a b.o ,生成libxxx.a文件:libtext.a
    在这里插入图片描述

库的使用

给别人使用库时候,就给xxx.a 和 .h 就行。

编译gcc 主函数.c -lxxx -L ./ -o mainProStatic

-lxxx是-l 加上上面生成的libxxx.a 的xxx
-ltext ,-l 是指定要用的动态库,库名砍头(lib)去尾(.a)

gcc test.c -ltext -L ./ -o mainProStatic  

Linux基础—” Linux静态动态库及相关编程“ 面试必问的知识点你了解了嘛_第4张图片

-ltext ,-l 是指定要链接的库,库名砍头(lib)去尾(.a)

-L 告诉gcc编译器从-L指定的路径去找静态库。默认是从/usr/lib 或者从/usr/local/lib去找

gcc calculatorT.c -lcalc -L ./ -o mainProDy libcalc.so

3. 动态库

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

优点:小

  1. 小,连接时候不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序可以共用,节省内存。
  2. 程序升级简单,因为app里没有库的源代码,升级后只要库的名字不变,函数名以及参数不变,只是实现做了优化,就能加载成功

缺点:慢 运行慢

  1. 加载速度比静态库慢
  2. 发布程序需要提供依赖的动态库

Linux基础—” Linux静态动态库及相关编程“ 面试必问的知识点你了解了嘛_第5张图片

命名规则
动态库的命名方式与静态库类似,前缀相同,为“lib”,后缀变为“.so。所以为“libmytime.so”

制作步骤
将源文件生成.o,需要加一个参数fpic
打包,gcc -shared -fpic 功能代码.c -o libxxx.so

-shared 是指定生成动态库
-fpic 是一种标准(fpic 选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码)

在这里插入图片描述

把制作好的库放到目录lib中,不放也行,其实只要有这个库就行,在这里,移到上层目录中的lib中

库的使用
编译 gcc 主程序.c -l库名 -L ./ -o mainProDy

gcc test.c -lclac -L ./ -o mainProDy 

Linux基础—” Linux静态动态库及相关编程“ 面试必问的知识点你了解了嘛_第6张图片
这时候我们运行./mainProDy ,发现执行不起来 ,找不到动态库。
在这里插入图片描述
动态和静态的区别就体现出来了,动态是在程序执行时动态(临时)由目标程序去调用。 运行的时候会去找动态库,但是找不到动态库。静态库不用去找静态库,因为它编译进去程序里了。

这时候我们编译

sudo cp libtext.so /usr/lib/

在运行./mainProDy 就可以运行了,因为它会默认去/usr/lib/找动态库
Linux基础—” Linux静态动态库及相关编程“ 面试必问的知识点你了解了嘛_第7张图片
如何指定运行的时候在当前路径下找呢?

指定运行的时候在当前路径

方法一
通过环境变量LD_LIBRARY_PATH指定动态库搜索路径。 export (环境变量)LD_LIBRARY_PATH=”LD_LIBRARY_PATH=“路径”

这样的方法也是只能在当前路径下使用,换目录就不行了。我们可以使用脚本来执行。

shell 脚本 vi start.sh

LD_LIBRARY_PATH="LD_LIBRARY_PATH=“/home/pi/ku"
./mainProDy

给脚本加可执行权限 chmod +x start.sh
在运行

./start.sh

脚本复习来点击这里

方法二
在编译目标代码时指定该程序的动态库搜索路径。 还可以在编译目标代码时指定程序的动态库搜索路径。通过gcc
的参数”-Wl,-rpath,”指定

你可能感兴趣的:(Linux,开发,linux,c语言,ubuntu)