Linux 库文件

1.什么是库文件

库文件是计算机上的一类文件,提供给使用者一些开箱即用的变量、函数或类。库文件分为静态库动态库,静态库和动态库的区别体现在程序的链接阶段:静态库在程序的链接阶段被复制到了程序中;动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。使用动态库系统只需载入一次,不同的程序可以得到内存中相同的动态库的副本,因此节省了很多内存,而且使用动态库也便于模块化更新程序。

2.库文件的特点

  • 库文件的主要作用就是为了让代码具有重用性,大大提高了我们的开发效率

  • 可以让程序具有后续的可维护性

注意:在windows 系统中库文件的扩展名为 .dll 文件 而Linux系统中的库文件扩展名就不是dll文件

3.库文件分为(Linux系统中)

3.1库文件会分为 静态库文件和动态库文件

  • 静态库:静态库文件在程序链接阶段被复制到程序中

  • 动态库:动态库在链接阶段没有被复制到程序中,而是程序在运行的时候,有系统自动分配

静态库(书店,只卖不借)
  • 静态库的文件扩展名为.a结尾

  • 特点:在链接阶段会复制到程序中

  • 优点:当我们在运行程序的时候,不会出现库文件找不到的情况,,因为程序在链接阶段就已经将库文件复制到程序中

  • 缺点:

    • 会占用更多的空间

    • 不利于功能的更新

动态库(图书馆,只借不卖)
  • 动态库的扩展名为.so 结尾

  • 特点:动态库在链接阶段没有复制,在程序执行的时候,有系统自动分配

  • 优点:

    • 相对静态库,占用的空间较小

    • 对程序的执行效率更高

    • 易于程序的更新

  • 缺点:在程序运行的时候,需要依赖库文件,如果库文件不存在则程序运行的时候会出现 库文件 找不到的情况

    • 在windows 中 运行某些程序的时候,可能就会出现 xxxxx.dll 文件不存在

4.如何制作库文件

在linux中如果需要创建静态库文件步骤如下

  • 编写一个源代码文件(就是C文件),将所有的功能设置到库文件中,将库文件的核心代码写到这个源文件中

  • 将这个制作静态库文件的变成 .o 对象文件(.o文件是制作库文件的原材料),无论是动态库还是静态库,都需要这个.o文件

    • xxxx.c => xxxx.o

  • 使用内置的ar命令创建静态库文件(可以得到一个.a文件)

  • 在其它程序中使用静态库文件

5.静态库案例实现过程

5.1 创建一个头文件(libmath.h)

#ifndef LIBMATH_H
#define LIBMATH_H

// 声明函数 一个函数用于 加法操作  一个函数用于减法操作
int jia(int a,int b);
int jian(int a,int b);

#endif

5.2 创建一个源文件(制作库文件的源文件)

// 引入头文件
#include "libmath.h"
// 定义函数
int jia(int a,int b){
    return a + b;
}

int jian(int a,int b){
    return a - b;
}

5.3 将制作库文件的源文件编译成.o文件(对象文件)

// gcc -c 源文件.c -o 对象文件.o
例如: dwg@DESKTOP-AI4K3V2:/Linux/day03/code$ gcc -c libmath.c -o libmath.o

5.4 使用 .o 文件制作静态库文件

ar rcs lib库文件名.a xxx.o 文件
  • r:替换库文件中现有的对象文件(.o),如果文件存在,则替换如果不存在则创建

  • c:创建一个新的静态库文件(如果库文件不存在则创建)

  • s:设置一个索引(主要的作用在链接的时候,有一定的速度优化)

注意:制作库文件的文件名必须以 lib开头,如果是静态库则是 .a 结尾的

5.5创建一个程序文件(使用静态库文件)

#include <stdio.h>
#include "libmath.h"
int main(int argc, char const *argv[])
{
    int res = jia(10,20);
    printf("10+20的结果是:%d\n",res);
    res = jian(30,20);
    printf("30-20的结果是:%d\n",res);
    return 0;
}

在编译的时候出现报错!!没有找到 jia 和 jian 的函数

5.6 将程序链接到静态库

gcc 自己的程序文件.c -L. -l库名 -o 可执行程序名
  • -L:告诉编译器在当前目录下查找库文件

  • -l:要链接的库文件的文件名(库名的位置不要写lib,结尾也不要写扩展名 .a)

6.动态库案例实现过程

6.1和6.2 同上

定义 源文件

6.3 编译源代码为 .o 文件

静态库 制作 .o 文件的命令:
gcc -c 源文件.c -o 对象文件.o
动态库 制作 .o 文件的命令:
gcc -fPIC -c 源文件.c -o 对象文件.o

6.4 将 .o 文件编译成 动态库文件(.so)

gcc -shared -o lib动态库的文件名.so 对象文件.o

gcc -shared -o lib动态库的文件名.so 对象文件.o

  • -shared 这个参数就是告诉 gcc 编译器 生成一个动态库文件而不是可执行程序 或 静态库文件

6.5 将程序链接到动态库

gcc 程序文件.c -L. -l库名 -o 可执行程序名

gcc 程序文件.c -L. -l库名 -o 可执行程序名

6.6 执行程序查看结果

./可执行程序

直接执行会报错:

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

原因就是没有找到库文件

需要将动态库文件 存放到 指定的系统目录中

存放 库文件 的目录是: /usr/lib

7.对比

  • 静态库:

    • 源程序.c => 源程序得到的.o => 得到静态库文件 .a =>

      • 将.a文件和自己的程序链接 => a.c

      • 将.a文件和自己的程序链接 => b.c

      • 将.a文件和自己的程序链接 => c.c

    • 如果库文件的 核心功能 更新或 代码修改 后 需要重新将所有的 a.cb.cc.c 文件 都需要重新 链接

  • 动态库:

    • 源程序.c => 源程序得到的.o => 得到静态库文件 .so =>

      • 将.so文件和自己的程序链接 => a.c

      • 将.so文件和自己的程序链接 => b.c

      • 将.so文件和自己的程序链接 => c.c

    • 如果动态库文件被修改,只需要覆盖原有的动态库文件即可,a.c b.c c.c文件并不需要重新链接

8.问题

如果当前项目目录中 同时用 静态库动态库

libmath.a

libmath.so

test.c 将 test.c 和 动态库或静态库做链接

#无论是动态库还是静态库 链接的时候使用的都是如下命令
gcc test.c -L. -lmath -o main   # 默认是 动态库
gcc test.c -L. -lmath -o main -static  # 默认是 动态库

如果不设置 任何参数做区别,默认链接的是 动态库

如果需要链接的事静态库则需要 在链接命令后 添加 -static 参数就是链接静态库

在开发期间,使用动态库较多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值