Linux下静态库与动态库制作及分文件编程

Linux下静态库与动态库制作及分文件编程

文章目录

  • Linux下静态库与动态库制作及分文件编程
    • 1.分文件编程
      • 1.1优点
      • 1.2操作逻辑
      • 1.3示例
    • 2.Linux库的概念
    • 3.静态库的制作与使用
      • 3.1优缺点
      • 3.2命名规则
      • 3.3制作步骤
      • 3.4开始享用
    • 4.动态库的制作与使用
      • 4.1优缺点
      • 4.2动态库命名规则
      • 4.3制作步骤
      • 4.4开始享用

1.分文件编程

这部分玩过单片机的都有所了解,在.c文件很多的时候,需要分文件编程,也叫模块化编程。

1.1优点

● 分模块的编程思想;

● 便于功能责任划分;

● 方便后期的维护和调试;

● 主程序更加简洁。

1.2操作逻辑

一篇代码基本可以分为三个部分,头文件部分,功能区部分,主函数main部分。那么分文件编程就是将这三个模块分别生成单独的代码文件。

● 功能区.c :只写功能实现的代码部分,可以不写头文件

● 主函数.c :写主函数main()的部分 ,和自己生成的“头文件.h”,用双引号“”,不用<>。

● 头文件.h :代码需要的所有头文件首先要写进去,然后功能区定义的函数及变量要写入(只写函数定义的区域,末尾加分号)。作用在于连接功能区代码和主函数代码。

1.3示例

输入两个数,分别计算出加减乘除后的值。

源代码示例(没用使用分文件编程的方式)

image-20240826095245822

代码拆分:采用分文件编程,将头文件区,功能代码区,主函数区分别建立代码文件

demo.h —— 头文件

#ifndef __DEMO_H		//加入预编译,防止重复加入头文件,命令方式以大写的头文件为名
#define __DEMO_H	#include <stdio.h>int add(int x,int y);//加法
int sub(int x,int y);//减法
int mul(int x,int y);//乘法
float div(int x,int y);//除法#endif

demo.c —— 主函数

#include "demo.h"//自建头文件,用双引号“”,里面包含功能区函数的定义及参数
//连接主函数和功能区代码 
int main()
{int data1;int data2;int value;printf("input a num:\n");scanf("%d",&data1);printf("input a num:\n");scanf("%d",&data2);printf("=============\n");printf("%d+%d=%d\n",data1,data2,add(data1,data2));//加printf("%d-%d=%d\n",data1,data2,sub(data1,data2));//减printf("%dx%d=%d\n",data1,data2,mul(data1,data2));//乘printf("%d/%d=%f\n",data1,data2,(float)div(data1,data2));//除return 0;
}

demo1.c —— 功能代码区

#include "demo.h"	//一般都会加自己的头文件,因为有些宏定义都会放到这个.h里面int add(int x,int y)//加法
{return x+y;
}
int sub(int x,int y)//减法
{return x-y;
}
int mul(int x,int y)//乘法
{return x*y;
}
float div(int x,int y)//除法
{return (float)x/y;
}

编译

//1.最笨的
gcc demo.c main.c
//2.利用*通配符,编译所有以.c为结尾的文件
gcc *.c

2.Linux库的概念

一个“程序函数库”简单的说就是一个文件包含了一些编译好的代码和数据,这些编译好的代码和数据可以在事后供其他的程序使用。程序函数库可以使整个程序更加模块化,更容易重新编译,而且更方便升级。

程序函数库可分为3种类型:静态函数库(static libraries)、共享函数库(shared libraries)、动态加载函数库(dynamically loaded libraries): (静态库,动态库,共享库)

1、静态函数库,是在程序执行前就加入到目标程序中去了 ;

通俗点说明:你可以使用我的代码,但是你不能看我的代码;

编译时,会链接到我们生成的库文件,程序可以正常编译运行,但如果常规使用vi打开库文件,就是一页乱码。

就是把上面的.c文件封装起来融合到主文件了,只有一个.h文件供你调用。

2、动态函数库同共享函数库是一个东西(在linux上叫共享对象库, 文件后缀是.so ,windows上叫动态加载函数库, 文件后缀是*.dll)

假如只有一个文件,那么静态库就很方便,但是如果有一百个文件,都用到了这个库文件,都融合到文件里面就会使得文件占得空间巨大,而且如果这个库文件更新迭代后,所有文件都要重新编译一下,如果是使用的动态库或者说共享库的话,这一百个文件共用这一个库文件,那么会省下很大一部分空间,在更新升级迭代后只需更新这一个库文件即可。

Linux中命名系统中共享库的规则

image-20240826102401211

3.静态库的制作与使用

目前不是那么常用了,不如动态库的种种,但是还是要学一下

静态函数库:是在程序执行前(编译)就加入到目标程序中去了 ;一般将功能性代码生成库文件

3.1优缺点

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

缺点:
● 链接时完整的拷贝到可执行文件中,被多次使用就会有多份冗余拷贝;
● 更新,部署,发布麻烦;

3.2命名规则

静态库文件的命名方式:“libxxx.a”,库名前加“lib”,后缀用“.a”,“xxx”为静态库名

动态库以.so为后缀

3.3制作步骤

原材料:xxx.c或者.cpp文件

  1. 制作成.o文件(-c在前在后无所谓)
gcc  -c xxx.c
  1. 生成静态库文件
ar rcs libtest.a xxx.o	//单个
ar rcs libtest.a xxx.o xxx.o //多个

生成的静态库文件通过主函数的链接后,正常编译运行,但并不能打开库文件查看里面的内容,也是库文件制作的目的所在

image-20240826104258329

其中:

ar rcs为固定命令,lib为固定开头,.a为固定结尾,中间的名字自己起

ar 命令里的内容 :

image-20240826104415900

3.4开始享用

你只知道他的头文件里面的函数有什么,怎么用,但是不知道这个函数具体是怎么实现的

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 //运行成功

4.动态库的制作与使用

动态函数库:是在程序执行时动态(临时)由目标程序去调用

4.1优缺点

优点:

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

缺点:

  • 加载速度比静态库慢;
  • 发布程序时需要提供依赖的动态库;

4.2动态库命名规则

**动态库的命名方式:**与静态库类似,“libxxx.so”, 库名前加“lib”,后缀用“.so”,“xxx”为动态库名

4.3制作步骤

原材料:xxx.c 文件

  1. 将源文件生成.o,需要加一个参数fpic
gcc a.c b.c -c -fpic(fPIC)
  1. 生成.so文件:
gcc -shared  xxx.o -o libtest.so
//一步到位的操作,不再生成.o文件,直接到.so
gcc -shared  -fpic xxx.c -o libtest.sogcc -shared  -fpic xxx.c -o libtest.soarm-linux-gnueabihf-gcc -shared  -fpic *.c -o libtest.so

● -shared:必须使用的关键字,指定生成动态库;

● -fpic:执行标准,作用于编译阶段,在生成目标文件时就得使用该选项;

image-20240826111507976

4.4开始享用

gcc xxx.c -ltest -L./ 编译后生成默认a.out可执行程序,也可以自行-o生成执行程序

里面这些符号的含义,在静态库已做介绍,不再赘述

image-20240826112248056

编译没问题,但是结果出了问题。动态库运行和静态库的运行方式有区别的,静态库直接生在在可执行的程序中,而动态库是在程序执行时动态(临时)由目标程序去调用,需要去找到执行的文件目录,所以上面的动态库执行出错。

动态库默认不会去当前目录下找,而是去环境变量中找。

解决方法:把生成的动态库文件libtest.so拷贝到/usr/lib/这个路径下即可

为了让系统能找到要加载的共享库,有三种方法 :1.把库拷贝到/usr/lib和/lib目录下 
2.在LD_LIBRARY_PATH环境变量中添加库所在路径,,export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:你的动态库目录
3.添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新
sudo cp libtest.so /usr/lib/

image-20240826112347654

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/55451.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

说说你对es6中promise的理解?

ES6中的Promise是一个非常重要的特性&#xff0c;它为异步编程提供了一种更优雅、更简洁的解决方案。以下是我对ES6中Promise的理解&#xff1a; 一、Promise的基本概念 Promise是异步编程的一种解决方案&#xff0c;它代表了一个异步操作的最终完成&#xff08;或失败&#…

GO实战课】第五讲:电子商务网站(5)——用户管理和注册

1. 简介 本课程将探讨电子商务网站的用户管理和注册功能,以及使用GO语言实现。在本课程中,我们将介绍如何设计一个可扩展、可靠和高性能的用户管理和注册系统,并演示如何使用GO语言编写相关代码。 本课程的目标是帮助学生理解电子商务网站的用户管理和注册功能,并提供一个…

【数据结构】双向链表(Doubly Linked List)

双向链表&#xff08;Doubly Linked List&#xff09;是一种链式数据结构&#xff0c;它的每个节点都包含三个部分&#xff1a;数据、指向前一个节点的指针&#xff08;prev&#xff09;&#xff0c;以及指向下一个节点的指针&#xff08;next&#xff09;。与单向链表不同&…

基于Vue的汽车维修配件综合管理系统设计与实现SpringBoot后端源码

目录 1. 系统背景 2. 系统目标 3. 功能模块 4. 技术选型 5. 关键技术点 6. 实现步骤 7. 项目意义 8. 后期展望 1. 系统背景 市场需求分析&#xff1a;随着汽车保有量的不断增加&#xff0c;汽车维修和保养的需求日益增长。车主对维修质量和配件质量的要求也越来越高。汽…

class 004 选择 冒泡 插入排序

我感觉这个真是没有什么好讲的, 这个是比较简单的, 感觉没有什么必要写一篇博客, 而且这个这么简单的排序问题肯定有人已经有写好的帖子了, 肯定写的比我好, 所以我推荐大家直接去看“左程云”老师的讲解就很好了, 一定是能看懂的, 要是用文字形式再写一遍, 反而有点画蛇添足了…

java中有两个list列表,尽量少的去循环

java中有两个list列表&#xff0c;一个list列表是paymentRecord&#xff0c;另外一个list是listApplyBase&#xff0c;paymentRecord中的lendCode字段值跟listApplyBase中的repaymentCode字段值是对应的&#xff0c;用stream流去循环paymentRecord列表&#xff0c;然后判断当pa…

javascript中如何实现继承(附案例)

在 JavaScript 中&#xff0c;有多种实现继承的方法&#xff0c;最常用的有原型链继承、构造函数继承、组合继承和 class 继承&#xff08;ES6&#xff09;。下面以 ES6 的 class 继承为例&#xff0c;展示如何实现继承&#xff1a; 示例&#xff1a; // 父类 class Animal {…

React响应式数据useState

React响应式数据useState 最近学了React&#xff0c;发现与Vue大有不同&#xff0c;在Vue中实现数据的响应式通过ref()函数&#xff0c;React则是通过useState()函数 使用 语法&#xff1a;const [data, setData] useState(数据) 说明&#xff1a;将数据传给useState()&am…

CANoe_TestModule截图功能TestReportAddWindowCapture

前言 TestReportAddWindowCapture方法作为CAPL脚本中的一个重要功能&#xff0c;其能够将指定窗口的屏幕截图添加到测试报告中&#xff0c;对于记录和验证界面状态具有重要意义。本文将全面解析TestReportAddWindowCapture方法的使用方法、参数解释、示例应用以及注意事项&…

中小企业做网站需要考虑哪些因素?

中小企业在建设网站时&#xff0c;需要考虑的因素有很多。以下是一些主要考虑因素的介绍&#xff1a; 明确建站目的&#xff1a;中小企业需要明确自己建立网站的目的。是为了展示企业形象、推广产品&#xff0c;还是提供客户服务&#xff1f;不同的目的将决定网站的设计和功能…

R语言的下载、安装及环境配置(RstudioVSCode)

0x01 R语言篇 一、软件介绍 R for Windows是一个免费的用于统计计算和统计制图的优秀工具&#xff0c;是R语言开发工具。它拥有数据存储和处理系统、数组运算工具&#xff08;其向量、矩阵运算方面功能尤其强大&#xff09;、完整连贯的统计分析工具、优秀的统计制图等功能。…

2.创建第一个MySQL存储过程(2/10)

引言 在现代数据库管理中&#xff0c;存储过程扮演着至关重要的角色。它们是一组为了执行特定任务而编写的SQL语句集合&#xff0c;这些语句被保存在数据库中&#xff0c;并且可以被多次调用执行。存储过程不仅可以提高数据库操作的效率&#xff0c;还能增强数据的安全性和一致…

2-113 基于matlab的图像的配准融合

基于matlab的图像的配准融合&#xff0c;采用互信息配准&#xff0c;PV差值&#xff0c;powell算法&#xff0c;小波变换的图像融合算法。在GUI界面输入两幅图像&#xff0c;完成图像的配准融合。融合图像要求像素 一样。程序代码已经有详细的注释。程序已调通&#xff0c;可直…

多个单链表的合成

建立两个非递减有序单链表&#xff0c;然后合并成一个非递增有序的单链表。 注意&#xff1a;建立非递减有序的单链表&#xff0c;需要采用创建单链表的算法 输入格式: 1 9 5 7 3 0 2 8 4 6 0 输出格式: 9 8 7 6 5 4 3 2 1 输入样例: 在这里给出一组输入。例如&#xf…

鸿蒙harmonyos next纯flutter开发环境搭建

公司app是用纯flutter开发的&#xff0c;目前支持android和iOS&#xff0c;后续估计也会支持鸿蒙harmonyos。目前谷歌flutter并没有支持咱们国产手机操作系统鸿蒙harmonyos&#xff0c;于是乎国内有个叫OpenHarmony-SIG的组织&#xff0c;去做了鸿蒙harmonyos适配flutter开发的…

ROS无人机机械爪使用

引言&#xff1a;使用飞控的主通道5-8作为舵机控制输出&#xff0c;需要提前设置好飞控参数&#xff0c;否则无效。本节资料文件尚未整理完毕&#xff0c;整理完毕后会在B站进行视频讲解&#xff0c;并进行开源 1、启动mavros通信&#xff0c;用于订阅遥控器的按键信息&#x…

harbor https配置

安装docker compose curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo yum -y install docker-compose docker-compose version生成自建CA证书 生成CA私钥&#xff1a; openssl genrsa -out /path/ca/ca.key 4096生成ca的自签名证书: open…

【力扣 | SQL题 | 每日四题】力扣1783,1757,1747,1623,1468,1661

昨天晚上睡着了&#xff0c;今天把昨天的每日一题给补上。 1. 力扣1783&#xff1a;大满贯数量 1.1 题目&#xff1a; 表&#xff1a;Players ------------------------- | Column Name | Type | ------------------------- | player_id | int | | player_na…

【AI知识点】词嵌入(Word Embedding)

词嵌入&#xff08;Word Embedding&#xff09;是自然语言处理&#xff08;NLP&#xff09;中的一种技术&#xff0c;用于将词语或短语映射为具有固定维度的实数向量。这些向量&#xff08;嵌入向量&#xff09;能够捕捉词语之间的语义相似性&#xff0c;即将语义相近的词映射到…

oracle 新建用户,用户插入数据报错:ORA-01950: 对表空间 ‘USERS‘ 无权限

oracle 新建用户&#xff0c;用户插入数据报错:ORA-01950: 对表空间 ‘USERS’ 无权限 根据业务需求创建了一个新的表空间和一个新的用户&#xff0c;当用这个新用户创建表时&#xff0c;报错&#xff1a;ORA-01950: 表空 间’USERS’中无权限。我已经把创建表的权限赋给了此用…