Linux库的认知与使用
创始人
2024-04-04 02:20:27
0

文章目录

    • 一、库的认知
    • 1.库的概念
    • 2.库的分类
    • (1)静态库
    • (2)动态库
    • 二、库的生成与使用
    • 1.静态库的生成与使用
    • (1)静态库命名规则
    • (2)静态库制作的步骤
    • (3) 静态库的使用
    • (4)静态库示生成与使用示例
    • 2.动态库的生成与使用
    • (1)动态库命名规则
    • (2)动态库制作的步骤
    • (3)动态库的使用
    • 解决方案(设置动态库可以的搜索路径)

一、库的认知

1.库的概念

库,本质上来说是一种可执行代码的二进制形式一个文件包含了一些编译好的代码和数据),可以被操作系统载入内存执行。
程序函数库可以使整个程序更加模块化更容易重新编译,而且更方便升级

2.库的分类

程序函数库可分为2种类型:
静态函数库,动态加载函数库
linux下
静态库:lib库名.a
动态库:lib库名.so(shared object)
window下:
静态库:lib库名.lib
动态库:lib库名.dll(dynamic link library)

(1)静态库

  • 简介:
    之所以称之为静态库,是因为在链接阶段,会将汇编生成的目标文件.o 与 引用的库一起链接到可执行文件中。对应的链接方式称为 静态链接
    如果多个进程需要引用到静态库,在内存中就会存在多份拷贝。

  • 静态库的特点:
    ①静态库对函数库的链接是在编译期完成的。执行期间代码装载速度快
    ②使可执行文件变大,浪费空间和资源(占空间)
    ③对程序的更新、部署与发布不方便,需要全量更新。如果 某一个静态库更新了,所有使用它的应用程序都需要重新编译、发布给用户。

  • 优点:
    1)静态库在编译的时候就被打包到应用程序中,所以其加载的速度快
    2)发布程序的时候无需提供静态库,因为已经在app中,移植方便

  • 缺点:
    1)链接时完整的拷贝到可执行文件中,被多次使用就会有多份冗余拷贝

  1. 更新,部署,发布麻烦

(2)动态库

  • 简介:
    在程序编译时并不会链接到目标代码中,而是在运行时才被载入。不同的应用程序如果调用相同的库,那么在内存中只需要有一份该共享库的实例,避免了空间浪费问题。同时也解决了静态库对程序的更新的依赖,用户只需更新动态库即可。

  • 动态库特点:
    ①动态库把对一些库函数的链接载入推迟到程序运行时期(占时间)。
    可以实现进程之间的资源共享。(因此动态库也称为共享库)
    ③将一些程序升级变得简单,不需要重新编译,属于增量更新。

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

  • 缺点:
    1)加载速度比静态库慢
    2)发布程序时需要提供依赖的动态库

二、库的生成与使用

1.静态库的生成与使用

(1)静态库命名规则

静态库文件名的命名方式是libxxx.a,库名前加lib,后缀用.axxx为静态库名。

(2)静态库制作的步骤

① 准备需要做成库的文件.c或.cpp文件
② 首先将.c文件生成.o文件,通过 gcc xxxx.c -c 生成
③ 将.o文件进行打包成后缀为.a的静态库文件,执行下列命令进行打包:

ar rcs libxxx.a xxx.o 

(3) 静态库的使用

gcc main_cal.c -lstaticCal -L ./ -o mainTest

-l:指定要用的静态库,库名要看头去尾(即要去掉lib和后缀.a),(-lmystatic)
-L:告诉gcc编译器从-L指定的路径去找静态库,如果没有指定,则默认从/usr/lib或/usr/local/lib去找 ,则这里有指定./,-L ./的意思就是从当前路径去找
-o(小写的O):指定生成的可执行文件

(4)静态库示生成与使用示例

例:要生成库的文件是calculator.c
示例代码:

  • calculator.c:
int add(int a,int b)
{return a+b;
}
int sub(int a,int b)
{return a-b;
}float div(int a,int b)
{return (float)a/b;
}
int mul(int a,int b)
{return a*b;
}
  • calculator.h:
int add(int a,int b);
int sub(int a,int b);
float div(int a,int b);
int mul(int a,int b);
  • main_cal.c :
#include 
#include "calculator.h"int main()
{int a,b;char operator;printf("输入数字n1:\n");scanf("%d",&a);printf("输入数字n2:\n");scanf("%d",&b);getchar();//输入第二个数字后回敲入一个空格,需要被接受掉,否则后面的运算符无法接受printf("输入算法(+,-,*,/):\n");scanf("%c",&operator);printf("输入的算式是:%d %c %d",a,operator,b);switch (operator){case'+' :printf(" = %d\n",add(a,b));break;case'-':printf(" = %d\n",sub(a,b));break;case'*':printf(" = %d\n",mul(a,b));break;case'/':printf(" = %f\n",div(a,b));break;}return 0;
}

① 首先生成.o文件

gcc calculator.c -c

在这里插入图片描述
② 将.o文件制作为静态库:

ar rcs libstaticCal.a calculator.o

在这里插入图片描述
生成了libstaticCal.a库文件
③ 使用静态库

gcc main_cal.c -lstaticCal -L ./ -o mainTest
  • 运行结果:
    在这里插入图片描述

2.动态库的生成与使用

(1)动态库命名规则

动态库的命名方式与静态库类似,前缀相同,为lib,后缀变为.so,所以为libxxx.so
后缀用.soxxx为动态库名。

(2)动态库制作的步骤

① 准备需要做成库的文件.c或.cpp文件
② 首先将.c文件生成.o文件,需要加-fpic:gcc xxx.c -c -fpic

-fpic:标准,fPIC 选项作用于编译阶段,在生成目标文件时就得使用该选项,以**生成位置无关的代码**。

③ 将.o文件进行打包成后缀为.so的动态库文件,执行下列命令进行打包:

gcc -shared xxx.o -o libxxx.so
-shared:指定生成动态库

(3)动态库的使用

gcc main_cal.c -ldynamicCal -L ./ -o mainTest

与静态库的使用方法一致,但是当运行mainTest时会报错:
在这里插入图片描述
此时会提示No such file or directory,这是因为在调用动态库时,在运行过程中会寻找此库一般会在 /usr/lib/ 目录下找文件;从而找不到libdynamicCal.so这个文件。
因此这里需要设置动态可以的搜索路径

解决方案(设置动态库可以的搜索路径)

  • 方案一:
    将生成的动态库拷贝到 /usr/lib/中:
sudo cp libdynamicCal.so /usr/lib

在这里插入图片描述
可以正常使用动态库

  • 方案二:
    将生成的库所在目录加入到环境变量(临时的):
export LD_LIBRARY_PATH="/home/zh1/STEP3/库的认知"

在这里插入图片描述
可正常运行
但是这种方法有缺陷,重启后变无法找到刚配置的环境变量,需要重新配置,若采用这种方法使用动态库一般需要编写脚本,例:

export LD_LIBRARY_PATH="/home/zh2/STEP3/库的认知"./mainTest

赋予脚本可执行权限

chmod +x start.sh

执行脚本即可:
在这里插入图片描述

  • 方案三
    在配置文件/etc/ld.so.conf中指定动态库搜索路径。(永久的)

/etc/ld.so.conf.d 路径中 添加 *.conf 例:mylib.conf

 cd /etc/ld.so.conf.d

创建mylib.conf文件

sudo vi mylib.conf

将所要指定的动态库搜索路径加入mylib.conf
在这里插入图片描述
再执行:

 sudo ldconfig
  • 方案四
    将生成的库所在目录加入到环境变量(永久的):

打开/etc/profile

sudo vi /etc/profile

在最后添加下列内容:

export  LD_LIBRARY_PATH=/home/zh1/STEP3/库的认知:$LD_LIBRARY_PATH

保存退出后执行:

source /etc/profile

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...