Linux分文件编程:静态库与动态库的生成和使用
目录
一,Linux库引入之分文件编程
① 简单说明
② 分文件编程优点
③ 操作逻辑
④ 代码实现说明
二,Linux库的基本说明
三,Linux库之静态库的生成与使用
① 静态库命名规则
② 静态库制作步骤
③ 静态库的使用
四,Linux库之动态库的生成与使用
① 动态库命名规则
② 动态库制作步骤
③ 动态库的使用
一,Linux库引入之分文件编程
① 简单说明
一般写代码demo时,习惯用一个代码文件进行代码编辑和编译。如果代码工程量大,实现功能多时,使用一个代码文件编写代码,就会显得代码冗长,繁杂,也不便后期维护。于是,便出现了分文件编程的方式。
分文件编程类似我之前写的博文:C语言简单工厂模式的实现,两者操作原理大同小异。
② 分文件编程优点
● 分模块的编程思想;
● 便于功能责任划分;
● 方便后期的维护和调试;
● 主程序更加简洁。
③ 操作逻辑
一篇代码基本可以分为三个部分,头文件部分,功能区部分,主函数main部分。那么分文件编程就是将这三个模块分别生成单独的代码文件。
● 功能区.c :只写功能实现的代码部分,可以不写头文件
● 主函数.c :写主函数main()的部分 ,和自己生成的“头文件.h”,用双引号“”,不用<>。
● 头文件.h :代码需要的所有头文件首先要写进去,然后功能区定义的函数及变量要写入(只写函数定义的区域,末尾加分号)。作用在于连接功能区代码和主函数代码。
④ 代码实现说明
输入两个数,分别计算出加减乘除后的值。
🔺源代码示例(没用使用分文件编程的方式)
orangepi@orangepizero2:~/file$ ./a.out
input a num:
66
input a num:
22
=============
66+22=88
66-22=44
66x22=1452
66/22=3.000000
🔺 代码拆分:将头文件区,功能代码区,主函数区分别建立代码文件
● 头文件 —— demo.h
● 主函数区 —— demo.c
● 功能函数 —— demo1.c
demo.h —— 头文件
1 #include <stdio.h>23 int add(int x,int y);//加法4 int sub(int x,int y);//减法5 int mul(int x,int y);//乘法6 float div(int x,int y);//除法
demo.c —— 主函数
2 #include "demo.h"//自建头文件,用双引号“”,里面包含功能区函数的定义及参数3 //连接主函数和功能区代码 4 int main()5 {6 int data1;7 int data2;8 int value;910 printf("input a num:\n");11 scanf("%d",&data1);12 printf("input a num:\n");13 scanf("%d",&data2);1415 printf("=============\n");1617 printf("%d+%d=%d\n",data1,data2,add(data1,data2));//加18 printf("%d-%d=%d\n",data1,data2,sub(data1,data2));//减19 printf("%dx%d=%d\n",data1,data2,mul(data1,data2));//乘20 printf("%d/%d=%f\n",data1,data2,(float)div(data1,data2));//除21 return 0;22 }
demo1.c —— 功能代码区
1 int add(int x,int y)//加法2 {3 return x+y;4 }5 int sub(int x,int y)//减法6 {7 return x-y;8 }9 int mul(int x,int y)//乘法10 {11 return x*y;12 }13 float div(int x,int y)//除法14 {15 return (float)x/y;16 }
编译说明:
二,Linux库的基本说明
一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数据可以在事后供其他的程序使用。程序函数库可以使整个程序更加模块化,更容易重新编译,而且更方便升级。
通俗点说明:你可以使用我的代码,但是你不能看我的代码;
编译时,会链接到我们生成的库文件,程序可以正常编译运行,但如果常规使用vi打开库文件,就是一页乱码。
程序函数库可分为3种类型:静态函数库(static libraries)、共享函数库(shared libraries)、动态加载函数(dynamicallyloaded libraries);
● 静态函数库:是在程序执行前就加入到目标程序中去了 ;
● 动态函数库与共享函数库:两者其实一样(在linux上叫共享对象库, 文件后缀是.so;windows上叫动态加载函数库, 文件后缀是.dll)
三,Linux库之静态库的生成与使用
静态函数库:是在程序执行前(编译)就加入到目标程序中去了 ;一般将功能性代码生成库文件
优点:
● 静态库在编译的时候就被打包到应用程序中,所以其加载的速度快;
● 发布程序的时候无需提供静态库,因为已经在app中,移植方便;
缺点:
● 链接时完整的拷贝到可执行文件中,被多次使用就会有多份冗余拷贝;
● 更新,部署,发布麻烦;
① 静态库命名规则
静态库文件的命名方式:“libxxx.a”,库名前加“lib”,后缀用“.a”,“xxx”为静态库名
② 静态库制作步骤
原材料:xxx.c文件
1,将 xxx.c 文件生成 xxx.o 文件:gcc xxx.c -c;
2,将 xxx.o 文件生成 libtest.a 静态库文件:ar rcs libtest.a xxx.o
生成的静态库文件通过主函数的链接后,正常编译运行,但并不能打开库文件查看里面的内容,也是库文件制作的目的所在
ar 命令里的内容 :
③ 静态库的使用
1,mv xxx.c ~ 将原先的功能文件和生成的.o文件移至工作目录,只留下.h头文件和主函数文件,还有生成的静态库文件。
2,gcc xxx.c -ltest -L./ 编译
● -l(L小写),链接生成的静态库文件,libtest.a需要“砍头去尾” test;
● -L:告诉gcc编译器从-L指定的路径去找静态库(当前路径)。默认是从/usr/lib或/usr/local/lib中去找
orangepi@orangepizero2:~/file$ ls
demo1.c demo1.o demo.c demo.h libtest.a
orangepi@orangepizero2:~/file$ mv demo1.c demo1.o ~ //把多余的文件移动到工作目录
orangepi@orangepizero2:~/file$ ls //只剩下库文件,头文件,主函数文件
demo.c demo.h libtest.a
orangepi@orangepizero2:~/file$ gcc demo.c -ltest -L./ //编译要链接库和路径
orangepi@orangepizero2:~/file$ ls //编译成功,生成可执行程序a.out
a.out demo.c demo.h libtest.a
orangepi@orangepizero2:~/file$ ./a.out //运行成功
input a num:
56
input a num:
89
=============
56+89=145
56-89=-33
56x89=4984
56/89=0.629214
四,Linux库之动态库的生成与使用
动态函数库:是在程序执行时动态(临时)由目标程序去调用
优点:
● 链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序可以共用,节省内存;
● 程序升级简单,因为app中没有库的源代码,升级之后只要库的名字不变,函数名与及参数不变,只是做了优化,就能加载成功;
缺点:
● 加载速度比静态库慢;
● 发布程序时需要提供依赖的动态库;
① 动态库命名规则
动态库的命名方式:“libxxx.so”, 库名前加“lib”,后缀用“.so”,“xxx”为动态库名
② 动态库制作步骤
原材料:xxx.c 文件
生成.so文件:gcc -shared -fpic xxx.c -o libtest.so
● -shared:必须使用的关键字,指定生成动态库;
● -fpic:执行标准,作用于编译阶段,在生成目标文件时就得使用该选项;
③ 动态库的使用
gcc xxx.c -ltest -L./ 编译后生成默认a.out可执行程序,也可以自行-o生成执行程序
● -l(L小写),链接生成的静态库文件,libtest.so需要“砍头去尾” test;
● -L:告诉gcc编译器从-L指定的路径去找静态库(当前路径)。默认是从/usr/lib或/usr/local/lib中去找
✳:编译没问题,但是结果出了问题。动态库运行和静态库的运行方式有区别的,静态库直接生在在可执行的程序中,而动态库是在程序执行时动态(临时)由目标程序去调用,需要去找到执行的文件目录,所以上面的动态库执行出错。
解决方法:把生成的动态库文件libtest.so拷贝到/usr/lib/这个路径下即可
相关文章:

Linux分文件编程:静态库与动态库的生成和使用
目录 一,Linux库引入之分文件编程 ① 简单说明 ② 分文件编程优点 ③ 操作逻辑 ④ 代码实现说明 二,Linux库的基本说明 三,Linux库之静态库的生成与使用 ① 静态库命名规则 ② 静态库制作步骤 ③ 静态库的使用 四,Linu…...

技术人的管理学-业务管理
主要内容前言制定计划遇到的问题?过程监控遇到的问题?复盘改进遇到的问题?通过PDCA循环解决业务管理问题总结前言 没有人天生就会管理,优秀的管理者都是在知行合一的过程中成长起来的,他们既需要系统的管理知识&#…...

Dubbo的独门绝技,SPI实现原理分析
文章目录前言普通SPI实现原理实例化扩展点源码分析扩展点加载流程分析LoadingStrategy分析接口定义接口实现加载原理loadClass方法分析自适应SPI实现原理自适应扩展代码生成分析自激活SPI简单使用原理分析Activate注解源码分析IOC实现原理objectFactory介绍总结AOP实现原理总结…...

单例模式,饿汉与懒汉
文章目录什么是单例模式单例模式的两种形式饿汉模式懒汉模式懒汉模式与饿汉模式是否线程安全懒汉模式的优化什么是单例模式 单例模式其实就是一种设计模式,跟象棋的棋谱一样,给出一些固定的套路帮助你更好的完成代码。设计模式有很多种,单例…...

Prometheus监控实战之Blackbox_exporter黑盒监测
1 Blackbox_exporter应用场景 blackbox_exporter是Prometheus官方提供的exporter之一,可以提供HTTP、HTTPS、DNS、TCP以及ICMP的方式对网络进行探测。 1.1 HTTP 测试 定义 Request Header信息 判断 Http status / Http Respones Header / Http Body内容 1.2 TC…...

【蓝桥杯集训·每日一题】AcWing 1051. 最大的和
文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴线性DP一、题目 1、原题链接 1051. 最大的和 2、题目描述 对于给定的整数序列 A{a1,a2,…,an},找出两个不重合连续子段,使得两子段中所有数字的和最…...

【Unity工具,简单应用】Photon + PUN 2,做一个简单多人在线聊天室
【Unity工具,简单应用】Photon PUN 2,做一个简单多人聊天室前置知识,安装,及简单UI大厅聊天室简单同步较复杂同步自定义同步最终效果前置知识,安装,及简单UI 【Unity工具,简单学习】PUN 2&…...

程序员增加收入实战 让小伙伴们都加个鸡腿
文章目录前言1️⃣一、发外包平台💁🏻♂️二、朋友介绍✍️三、打造自己的个人IP👋🏿四、混群拉单🤳🏿五、面试拉单💻六、技术顾问🦴七、开发个人项目总结:前言 程序员…...

GPIO四种输入和四种输出模式
GPIO的结构图如下所示: 最右端为I/O引脚,左端的器件位于芯片内部。I/O引脚并联了两个用于保护的二极管。 输入模式 从I/O引脚进来就遇到了两个开关和电阻,与VDD相连的为上拉电阻,与VSS相连的为下拉电阻。再连接到TTL施密特触发…...

ChatGPT能够改变时代吗?一点点思考
都知道ChatGPT的出现对整个世界产生了剧烈的影响,前不久出的ChatGPT4更是在ChatGPT3.5的基础上展现了更强的功能。比如说同一个问题,ChatGPT3.5还是乱答的,ChatGPT4已经能给出正确解了。当然这只能说明技术是进步的。 虽然如此,很…...

Markdown如何使用详细教程
目录 一、Markdown 标题 二、Markdown 段落 三、Markdown 字体 四、Markdown 分隔线 五、Markdown 列表 六、Markdown 引用 七、Markdown 代码 八、Markdown 链接 九、Markdown 图片 十、Markdown 表格 前言 当前许多网站都广泛使用 Markdown 来撰写博客,…...

HTML5庆祝生日蛋糕烟花特效
HTML5庆祝生日蛋糕烟花特效 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>HTML5 Birthday Cake Fireworks</title><style>canvas {position: absolute;top: 0;left: 0;z-index: -1;}</style> </h…...

算法套路四——反转链表
算法套路四——反转链表 算法示例一:LeetCode206. 反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 初始化pre为空,cur为头指针 pre指针:记录当前结点的前一个结点 cur指针:记录当…...

多线程 (六) wait和notify
🎉🎉🎉点进来你就是我的人了 博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔🦾&am…...

React--》状态管理工具—Mobx的讲解与使用
目录 Mobx的讲解与使用 Mobx环境配置 Mobx的基本使用 Mobx计算属性的使用 Mobx监听属性的使用 Mobx处理异步的使用 Mobx的模块化 Mobx的讲解与使用 Mobx是一个可以和React良好配合的集中状态管理工具,mobx和react的关系相当于vuex和vue之间的关系࿰…...

有效的括号长按键入验证外星语词典字符的最短距离用栈实现队列
有效的括号来源:杭哥20. 有效的括号 - 力扣(LeetCode)bool isValid(char * s) {int szstrlen(s);char stack[sz];int k0;for (int i0;i<sz;i){if (s[i]( || s[i][ || s[i]{){stack[k]s[i];}else{if (k0){return false;}else if (s[i]} &am…...

《前端开发者的进阶之路》
前端作为Web开发的重要领域之一,不断地发展和演变着。除了基本的HTML、CSS、JavaScript技能,前端开发者需要掌握更多的进阶知识才能应对不断变化的需求。本文将介绍一些前端的进阶知识,帮助前端开发者进一步提高自己的技能水平。1.框架和库在…...

为什么说网络安全是风口行业?是IT行业最后的红利?
前言 “没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。 网络安全行业特点 1、就业薪资非常高,涨薪快 2021年猎聘网发布网络安全行业就业薪资行业最高人均33.77万&…...

使用shell 脚本,批量解压一批zip文件,解压后的文件放在以原zip文件名前10个字符的文件夹中的例子
#!/bin/bash for file in *.zip dofolder$(echo $file | cut -c 1-10)mkdir $folderunzip -q $file -d $folder doneecho "All zip files have been extracted." # 说明: # 1. for循环遍历当前目录下的所有zip文件 # 2. 使用cut命令提取zip文件名前10个字…...

01 | Msyql系统架构
目录MySQL系统架构连接器查询缓存分析器优化器执行器MySQL系统架构 大体来说,MySQL分为Server层和引擎层两部分。 Server层包含链接器、查询缓存、分析器、优化器和执行器,而引擎层负责的是数据的存储和读取,支持InnoDB、Myisam、Memory等多…...

Linux命令---设备管理
Linux setleds命令Linux setleds命令用来设定键盘上方三个 LED 的状态。在 Linux 中,每一个虚拟主控台都有独立的设定。语法setleds [-v] [-L] [-D] [-F] [{|-}num] [{|-}caps] [{|-}scroll]参数:-F:预设的选项,设定虚拟主控台的状…...

前端入门:HTML5+CSS3+JAAVASCRIPT
1、 初识HTML HTML:Hyper Text Markup Language(超文本标记语言) 。 超文本包括:文字、图片、音频、视频、动画等。 1.1、W3C标准 1.2、HTML基本结构 示例: <!-- DOCTYPE:告诉浏览器,我们要使用什么规划,这里是HTML --> …...

【头歌实验】课外作业一:开通ECS及使用Linux命令
文章目录一、完成下列实验并截图二、简要回答“课堂考核”内容三、在头歌、华为云或阿里云官网上,找出自己的课外学习资源,制定小组的课程学习计划、专业学习计划。四、习题1.10一、完成下列实验并截图 1、实验《ECS云服务器新手上路》 https://develo…...

CMSIS-RTOS2 RTX5移植到GD32L233
1、CMSIS-RTOS2是什么? 关于CMSIS-RTOS2的官方描述如下: CMSIS-RTOS v2 (CMSIS-RTOS2) 为基于 Arm Cortex 处理器的设备提供通用 RTOS 接口。它为需要RTOS功能的软件组件提供了一个标准化的API,因此为用户和软件行业带…...

[网络原理] 网络中的基本概念
人生,本就是苦乐参半,这样的生活才是丰富多彩. 文章目录前言1. IP地址2. 端口号3. 协议4. 五元组5. 协议分层6. OSI七层模型7. TCP/IP协议8. 封装和分用9. 客户端与服务端10. 请求与响应前言 本章开始,我们开启网络部分的知识大门. 1. IP地址 1.定义: IP地址主要用于表示网络…...

BeanPostProcessor原理分析
文章目录一、BeanPostProcessor的作用1. 源码2. 使用案例二、Spring生命周期中的BeanPostProcessor三、BeanPostProcessor对PostConstruct的支持四、BeanPostProcessor中的顺序性五、总结一、BeanPostProcessor的作用 BeanPostProcessor提供了初始化前后回调的方法,…...

人工智能和网络安全,应该如何选择?
随着数字时代的到来,网络安全和人工智能成了科技创新产业的重要组成部分。也逐渐成了大多数人心中热门的行业选择。那么该如何抉择呢? 首先我们来了解下人工智能的发展前景: 如今,人工智能技术无论是在核心技术方面࿰…...

Flink预加载分区维表,实时更新配置信息
当前我们的业务场景,是基于dataStream代码, 维表数据量很大, 实时性要求很高,所以采用预加载分区维表模式, kafka广播流实时更新配置。 实现方案 1:job初始化时 每个分区open 只加载自己那部分的配置&…...

大数据现在找工作难么
大数据行业工作好找还是难找不是光靠嘴说出来的结合实际,看看市场上的招聘需求和岗位要求就大致知道了 要想符合企业用人规范,学历,工作经验,掌握技能都是非常重要的~ 先来看几个招聘网站的报告数据: Boss直聘发布的…...

【Linux】学会这些基本指令来上手Linux吧
前言上篇文章介绍了一些常用的指令,这篇文章再来介绍一下Linux必须学会的指令。一.时间相关的指令ate显示date 指定格式显示时间: date %Y:%m:%d date 用法:date [OPTION]... [FORMAT]1.在显示方面,使用者可以设定欲显示的格式&am…...