当前位置: 首页 > news >正文

C语言中的静态库和动态库的制作和使用

什么是库文件

单一模型

将程序中所有功能全部实现于一个单一的源文件内部。

编译时间长,不易于维护和升级,不易于协作开发。

分离模型

将程序中的不同的功能模块划分到不同的源文件中。

缩短编译时间,易于维护和升级,易于协作开发。

库文件

对多个目标文件的管理比较麻烦,可以将多个目标文件统一整理成一个库文件。

库文件可以直接在其他C语言程序中直接调用。

可以简单的把库文件理解成一种代码仓库,它提供给使用者一些可以直接拿来用的变量,函数或者类。

库文件一般指的是计算机上的一类文件,分为两种,一种叫做静态库,一种叫做动态库。

静态库

概述

静态库的本质是将多个目标文件打包成一个文件。

链接静态库就是将库中被调用的代码复制到调用模块中。

静态库的扩展名是.a,比如libxxx.a

静态库的构建

1、编辑库的实现代码和接口声明

  • 计算模块:calc.h,calc.c
  • 显示模块:show.h,show.c
  • 接口文件:math.h

2、编译成目标文件

gcc -c calc.c
gcc -c show.c

3、打包成静态库

ar -r libmath.a calc.o show.o

实战案例:构建 libmath.a 静态库

准备源文件

calc.h

  • 定义加法:int add(int a, int b);
  • 定义减法:int sub(int a, int b);
#ifndef __CALC_H_
#define __CALC_H_int add(int a, int b);
int sub(int a, int b);#endif // __CALC_H_

calc.c

  • 简单的实现加法
  • 简单的实现减法
#include "calc.h"int add(int a, int b){return a + b;
}int sub(int a, int b){return a - b;
}

show.h

#ifndef __SHOW_H_
#define __SHOW_H_void show(int a, char* op, int b, int res);#endif // __SHOW_H_

show.c

#include <stdio.h>
#include "show.h"void show(int a, char* op, int b, int res){printf("%d %s %d = %d\n", a, op, b, res);
}
编译C源文件
gcc -c calc.c
gcc -c show.c
构建静态库
ar -r libmath.a calc.o show.o
使用静态库文件

main.c

#include <stdio.h>
#include "calc.h"
#include "show.h"int main(){int a = 11;int b = 22;int res = add(a, b);show(a, "+", b, res);return 0;
}

编译并运行文件,此时把静态库文件也带上:

gcc main.c libmath.a -o main && ./main

输出结果如下:

11 + 22 = 33
使用接口文件优化

当我们的库越来越大的时候,头文件也会越来越多,这个是让用户分别引入每个头文件是不人性化的。

这个时候,我们可以给库配套一个相应的头文件,这个头文件中引入需要的所有其他头文件这个。这个与库对应的头文件就是我们这个库的接口文件。

math.h

#ifndef __MATH_H_
#define __MATH_H_#include "calc.h"
#include "show.h"#endif // __MATH_H_

main.c

#include <stdio.h>
#include "math.h"int main(){int a = 11;int b = 22;int res = add(a, b);show(a, "+", b, res);return 0;
}

动态库

概述

动态库的扩展名是.so。

动态库是被加载,调用的时候是根据内存地址去调用,而不是将代码复制到文件中。

动态库可以同时被多个进程使用。

实战案例:构建 libmath.so 动态库

准备源文件

calc.h

  • 定义加法:int add(int a, int b);
  • 定义减法:int sub(int a, int b);
#ifndef __CALC_H_
#define __CALC_H_int add(int a, int b);
int sub(int a, int b);#endif // __CALC_H_

calc.c

  • 简单的实现加法
  • 简单的实现减法
#include "calc.h"int add(int a, int b){return a + b;
}int sub(int a, int b){return a - b;
}

show.h

#ifndef __SHOW_H_
#define __SHOW_H_void show(int a, char* op, int b, int res);#endif // __SHOW_H_

show.c

#include <stdio.h>
#include "show.h"void show(int a, char* op, int b, int res){printf("%d %s %d = %d\n", a, op, b, res);
}
编译C源文件
gcc -c -fpic calc.c
gcc -c -fpic show.c
构建动态库
gcc -shared calc.o show.o -o libmath.so
使用动态库

main.c

#include <stdio.h>
#include "calc.h"
#include "show.h"int main(){int a = 11;int b = 22;int res = add(a, b);show(a, "+", b, res);return 0;
}

编译并运行文件,此时把静态库文件也带上:

# 先配置库所在的环境变量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.# 编译执行
gcc main.c libmath.so -o main && ./main

输出结果如下:

11 + 22 = 33
http://www.lryc.cn/news/346881.html

相关文章:

  • 【MySQL 数据宝典】【事务锁】- 002 事务控制的演进
  • 如何远程操作服务器中的Python编译器并将运行结果返回到Pycharm
  • C++入门指南(上)
  • Python 全栈系列244 nginx upstream 负载均衡 踩坑日记
  • 数据链路层——计算机网络学习笔记三
  • leetcode——反转链表
  • 类加载机制(双亲委派机制)
  • nss刷题(2)
  • 2024 年“泰迪杯”A 题:生产线的故障自动识别与人员配置--第四题(用遗传算法解决生产线排班问题--matlab代码)
  • 资产公物仓管理系统|实现国有资产智能化管理
  • 实用的 Google Chrome 命令
  • 动态规划算法:⼦数组、⼦串系列(数组中连续的⼀段)
  • 2010年认证杯SPSSPRO杯数学建模D题(第一阶段)服务网点的分布全过程文档及程序
  • docker-compose 安装ZLMediaKit,ffmpeg、VLC实现推流并播放
  • |Python新手小白中级教程|第二十八章:面向对象编程(类定义语法私有属性类的继承与多态)(4)
  • vue项目基于WebRTC实现一对一音视频通话
  • web 基础之 HTTP 请求
  • 嵌入式 - GPIO编程简介
  • 8种区块链开发者必须知道的顶级编程语言!
  • 十三、Redis哨兵模式--Sentinel
  • [力扣题解]1005. K 次取反后最大化的数组和
  • Web UI自动化测试--PO模式
  • Python进阶之-反射机制详解
  • day05-面向对象内存原理和数组
  • 从头理解transformer,注意力机制(下)
  • ORA-609频繁出现在alert.log,如何解决?
  • JVM 类加载机制
  • 亲测-wordpress文章实时同步发布修改删除多个站点的WP2WP插件
  • npm无法安装node-sass 的问题
  • springboot 引入第三方bean