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

c语言库文件

c语言库文件

  • 动态库
    • 动态库制作
      • 首先生成动态库文件名
      • 使用动态库编译
      • 动态库运行
      • 删除动态库
        • 1.sudo su
  • 静态库
    • 静态库制作
      • 需要将源文件.c转换成二进制文件.o(重定向文件)
      • 将重定向文件打包成静态库文件
      • 使用静态库文件
  • 静态库和动态库的区别
  • 复杂工程设定
    • 工程目录设定
      • 原始编译方式
      • 静态库编译
        • 生成重定向文件:我们将重定向文件生成到obj目录下
        • 生成静态库文件:我们将静态库存放到生成的lib目录
        • 使用静态库编译

库文件的概念

我们将已经实现的某些功能封装在一起,形成一个可以操作的函数库既可以方便我们函数调用,并且对代码进行了加密保护。
为了方便实现分装操作,我们将多个源文件(函数功能),打包成库,方便调用。
需要注意的是:库函数文件中只能包含功能性函数,不要将main函数封装进去

在这里插入图片描述

动态库

  • 1.库中的代码不会通过编译进入到程序里面,那么形成的可执行程序文件比较小
  • 2.由动态库编译的程序,需要运行这个程序的系统环境变量中存在这个库文件

动态库制作

1.所有的动态库后缀都是.so,前缀需要是lib,动态库的名字为:libxxx.so
2.直接将源文件生成为动态库文件

add.c

int add(int a, int b)
{return a + b;
}

add.h

#ifndef __ADD_H__
#define __ADD_H__
#include <stdio.h>
int add(int a, int b);
#endif

max.c

int max(int a, int b)
{return a > b ? a : b;
}

max.h

#ifndef __MAX_H__
#define __MAX_H__
#include <stdio.h>
int max(int a, int b);
#endif

main.c

#include <stdio.h>
#include "add.h"
#include "max.h"
int main()
{printf("add=%d\n", add(10, 20));printf("max=%d", max(100, 10));return 0;
}

首先生成动态库文件名

gcc -shared -fPIC -o 动态库文件名 源文件1 源文件2 源文件3...

表示将所有的源文件都编译成指定名字的动态库文件(.so文件)
选项:
-shared表示生成的库文件为.so动态库
-fPIC表示代码和地址无关,不需要被同模块重定位,生成可操作的PIC代码
比如:
将封装了加法功能函数的源文件aad.c 以及求最大值的函数源文件max.c
封装成库文件
gcc -shared -fPIC -o libfunc.so add.c max.c 动态库文件名 libxxx.so ,-o选项不要漏 ,不带main主函数

在这里插入图片描述

使用动态库编译

gcc 主函数.c -o 可执行文件名 -l库文件名 -I 头文件路径 -L 库文件路径
比如:
由于上面生成了一个名为funlibfun.so库文件
所以下面执行命令的为lfun
gcc main.c -o main -lfun -I ./ -L ./
说明:./表示在当前目录下查找文件
在这里插入图片描述

注意这个时候虽然动态库里面生成了,但是系统库里面依然没有 直接运行**./main**的话还是会报错

在这里插入图片描述

动态库运行

上面提到会报错
解决办法:将动态库文件拷贝到系统库位置

sudo cp libadd.so /lib

这个时候输入ls /lib发现找到了libfun这个库文件在这里插入图片描述

我们刚才命名的可执行文件为main因此这里直接执行./main就可以执行了

在这里插入图片描述

使用动态库的好处:

  • 1.隐藏了函数实现的代码,只暴露接口,提高代码的安全性
  • 2.可以直接使用库中的函数,而不需要重新实现函数
    比如:现在如果需要使用add函数,只需要新建一个源文件,做一下add函数的声明,就可以直接使用add函数。

在这里插入图片描述

在以上代码中我们发现只声明了 并没有定义但是他还是引用了我们之前定义的库函数
gcc -o main 9.c -L./book -lfun

  • main是最终生成的可执行的二进制文件
  • 9.c 是源文件
  • -L 后面接的是表示当前目录是库文件的搜索路径,这样编译器可以在当前目录中查找共享库 libfun.so,因为我的libfun.so是在book下面的所以./book
  • -l 后面接-lfun 表示链接 libfun.so

删除动态库

如果需要删除动态库文件,就需要删除/lib目录下的动态库.so文件,但是lib目录只能由管理员操作,所以要删除,需要先获得管理员权限。

sudo su
rm -rf 删除的文件名
1.sudo su

会先验证用户密码
查看lib下面的动态库ls /lib
在这里插入图片描述
cd /lib
进入lib文件
rm -rf libadd.so libfun.so 删除要删除的库文件
exit退出
在这里插入图片描述

在这里插入图片描述
删除过后再次执行文件报错,证明动态文件库已经被删

静态库

静态库特点

格式文件:libxxx.a 比如:libadd.a

  • 1.静态库里面的代码会进入到程序中,静态编译的程序比较大
  • 2.有静态库编译的程序,必须要在运行环境中存在这个库文件,才可以允许。

文件自己定义
文件可以接着用以上的文件

静态库制作

需要将源文件.c转换成二进制文件.o(重定向文件)

gcc 源文件.c -o 重定向文件.o -c
比如:gcc swap.c -o swap.o -cgcc -c  add.c -o add.o 

注意文件重定向需要一个个去执行

将重定向文件打包成静态库文件

ar cr libfunc11.a swap.o add.o

使用静态库文件

gcc 主函数.c -o 可执行文件 -l库文件 -I 头文件路径 -L 库文件路径
gcc main.c -o main -lfunc11 -I ./ -L ./

在这里插入图片描述
使用静态库的时候把生成的静态库文件复制一下就可以了
在这里插入图片描述

静态库和动态库的区别

1.动态库和静态库创建方式不同
2.动态编译程序的时候,不会将库中的代码加入到程序中,所以动态编译程序较小
3.静态编译程序的时候,会将库中的代码直接编译到程序中,所以静态编译程序较大

静态库的特点:
优点:可执行文件依赖较少,编译期间完成链接,装载快
缺点:可执行文件较大,可作为其他库的依赖,会造成多余的副本,升级不方便,必须重新编译

动态库的特点:
优点:动态库可以实现进程之间的资源共享,即存在一份就行,升级简单,不需要重新编译
缺点:运行期间必须加载代码,会减慢代码执行速度,程序需要的依赖较多,必须存在于系统库中

复杂工程设定

工程目录设定

实际开发中,我们会将不同的文件类型存放在不同的目录当中进行存储,此实程序会将数据内容分为不同的文件夹来保存资源

  • bin 可执行程序文件
  • inc头文件集合 .h
  • lib 存放库文件(.so文件和.a文件) 静态库 动态库
  • obj 存放重定向文件(.o文件)
  • src 存放源文件(.c文件)
  • main.c 入口文件

在这里插入图片描述

原始编译方式

gcc sawp.c add.c main.c -o main
gcc 带路径的源文件列表 -o 带路径的可执行文件 -I 头文件路径 -L 库文件路径 -l库名
gcc ./src/*.c main.c -o ./bin/main -I ./inc/

编译成功运行可执行文件就行

静态库编译

生成重定向文件:我们将重定向文件生成到obj目录下

gcc add.c -o add.o -c
gcc 带路径的源文件.c -o 带路径的重定向文件.o -I 头文件路径
gcc ./src/add.c -o ./obj/add.o -c -I ./inc/

生成静态库文件:我们将静态库存放到生成的lib目录
ar cr libfunc2.a add.o swap.o
ar cr libfunc2.a *.o
ar cr 带路径的静态库文件.a 带路径的重定向文件.o
ar cr ./lib/libfunc2.a ./obj/*.o
使用静态库编译
gcc main.c -o main -lfunc -I ./ -L ./
gcc main.c -o 带路径的可执行程序文件 -l静态库名 -I 头文件路径 -L 库文件路径
gcc main.c -o ./bin/main -lfunc2 -I ./inc/ -L ./lib/

http://www.mrgr.cn/news/52064.html

相关文章:

  • c++初阶数据结构速成
  • 自动驾驶系统研发系列—智能驾驶新技能:MEB低速紧急制动系统带来更多驾驶安全保障
  • 充电宝哪个品牌性价比高?2024精选五款推荐,新手买前必看!
  • 就是这个样的粗爆,手搓一个计算器:卡路里计算器
  • 产品经理图书推荐 《人工智能产品经理:AI时代PM修炼手册》
  • 基于单片机的搬运机器人控制系统
  • OpenCV高级图形用户界面(15)注册一个回调函数来处理鼠标事件的函数setMouseCallback()的使用
  • Cannot determine local hostname
  • KNN的 k 设置的过大会有什么问题
  • ZBrush和3D-Coat各自的优缺点是什么?
  • 番茄工作法计时器:高效时间管理利器
  • 鸿蒙开发案例:绘制中国象棋棋盘与棋子的技术教程
  • Java 枚举类
  • 自定义类型——结构体
  • c#编写的各类应用程序
  • 65.DDR3读写控制器的设计与验证(2)
  • 60. 排列序列
  • Windows11桌面快捷方式图标变为白色方块-如何解决
  • C++11 使用 {} 进行初始化
  • 【微信小程序_18_WXS脚本】