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

news2024/10/6 13:47:02

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.so
    gcc -shared  -fpic xxx.c -o libtest.so
    arm-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.coloradmin.cn/o/2192036.html

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

相关文章

Redis:list类型

Redis&#xff1a;list类型 list命令非阻塞LPUSHLRANGELPUSHXRPUSHRPUSHXLPOPRPOPLINDEXLINSERTLLENLREMLTRIMLSET 阻塞BLPOPBRPOP 内部编码ziplistlinkedlistquicklist 几乎每种语言都有顺序表、数组、链表这样的顺序结构&#xff0c;Redis也做出了相应的支持。 如图&#xff…

RAG:检索增强生成技术概览

Why 将大模型应用于实际业务场景时会发现&#xff0c;通用的基础大模型基本无法满足我们的实际业务需求&#xff0c;主要有以下几方面原因&#xff1a; 知识的局限性&#xff1a;大模型对于一些实时性的、非公开的或离线的数据是无法获取到的。幻觉问题&#xff1a;所有的AI模…

【Python游戏开发】贪吃蛇游戏demo拓展

拓展上一项目【Python游戏开发】贪吃蛇 实现穿墙效果 # 检测游戏是否结束 def check_gameover():global finished# 移除蛇头位置超过窗口判断for n in range(len(body) - 1):if(body[n].x snake_head.x and body[n].y snake_head.y):finished True # 状态检测 def ch…

嘴尚绝卤味:健康美味的双重奏

在当今快节奏的生活中&#xff0c;人们对美食的追求不再仅仅停留于味蕾的满足&#xff0c;更加注重食物的健康与营养。在这一背景下&#xff0c;"嘴尚绝卤味"以其独特的健康理念与精湛的制作工艺&#xff0c;成为了市场上备受瞩目的卤味品牌。本文将从"嘴尚绝卤…

Linux运维01:VMware创建虚拟机

视频链接&#xff1a;05.新建VM虚拟机_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1nW411L7xm/?p14&spm_id_from333.880.my_history.page.click&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.点击“创建虚拟机” 2.选择“自定义&#xff08;高级&#xff0…

15分钟学 Python 第41天:Python 爬虫入门(六)第二篇

Day41&#xff1a;Python爬取猫眼电影网站的电影信息 1. 项目背景 在本项目中&#xff0c;我们将使用 Python 爬虫技术从猫眼电影网站抓取电影信息。猫眼电影是一个知名的电影信息平台&#xff0c;提供了丰富的电影相关数据。通过这个练习&#xff0c;您将深入学习如何抓取动…

小白必看一文彻底搞懂 Transformer(图解+手撕)

Transformers 亮相以来彻底改变了深度学习模型。 今天&#xff0c;我们将揭示 Transformers 背后的核心概念&#xff1a;注意力机制、编码器-解码器架构、多头注意力等等。 通过 Python 代码片段&#xff0c;让你深入了解其原理。 技术交流群 前沿技术资讯、算法交流、求职…

用IMX6UL开发板编写按键输入实验

在之前我们都是讲解如何使用IMX6UL的GPIO输出控制等功能&#xff0c;IMX6U的IO不仅能作为输出&#xff0c;而且也可以作为输入&#xff0c;而我们开发板上具有一个按键&#xff0c;按键肯定是连接了一个IO口的额&#xff0c;我们在这一节将会把IO配置成输入功能&#xff0c;读取…

JAVA基础面试题汇总(持续更新)

1、精确运算场景使用浮点型运算问题 精确运算场景&#xff08;如金融领域计算应计利息&#xff09;计算数字&#xff0c;使用浮点型&#xff0c;由于精度丢失问题&#xff0c;会导致计算后的结果和预期不一致&#xff0c;使用Bigdecimal类型解决此问题&#xff0c;示例代码如下…

Java类的生命周期浅析

知识前提 在了解类的生命周期之前&#xff0c;有必要先了解一下jvm的内存结构。如下所示&#xff1a; 在了解完jvm的内存结构之后&#xff0c;就知道了例如堆区&#xff0c;栈区&#xff0c;常量池和方法区等概念。 也了解到了&#xff0c;编写的代码&#xff0c;是先需要通过…

使用pytdx获取股票信息总结

使用pytdx获取股票相关信息汇总 行情接口标准行情对接总结界面展示性能问题数据可靠性 附录代码 行情接口 pytdx中提供了hq&#xff08;标准行情&#xff09;及exhq&#xff08;扩展市场行情&#xff09;两种接口&#xff0c;扩展市场目前已经失效无法使用。 标准行情 这里只…

4. Getter和Setter注解与lombok

文章目录 1. 什么是Getter和Setter注解2. 什么是lombokjava自带的jar包 3. 从maven仓库里找lombok相关jar包4. 把jar包导入项目另一个jar包导入途径 5. 正式使用注解① 问题② 解决方案提示 6. 如果还想对某个成员变量添加限制怎么办7. 内容出处 1. 什么是Getter和Setter注解 官…

【包教包会】速通LLM《从头开始构建大型语言模型》免费pdf分享

介绍 在当今人工智能技术飞速发展的时代&#xff0c;大型语言模型&#xff08;LLM&#xff09;作为聊天机器人、文本生成和理解等应用的核心&#xff0c;已经成为研究和商业领域的关注焦点。尽管这些模型的应用无处不在&#xff0c;但对于大多数开发者来说&#xff0c;它们的工…

AI正悄然地影响着企业数字化转型

2022年底发布的ChatGPT将人工智能技术上升到了一个新的高度。如今&#xff0c;人工智能正彻底改变数字转型的进程&#xff0c;为企业提供优化运营和提升客户体验的机会。利用算法、数据分析、机器学习等人工智能技术结合企业自身情况&#xff0c;可以推动企业持续创新&#xff…

每日OJ题_牛客_mari和shiny_线性dp_C++_Java

目录 牛客_mari和shiny_线性dp 题目解析 C代码 Java代码 牛客_mari和shiny_线性dp mari和shiny (nowcoder.com) 描述&#xff1a; mari每天都非常shiny。她的目标是把正能量传达到世界的每个角落&#xff01; 有一天&#xff0c;她得到了一个仅由小写字母组成的字…

ElasticSearch 备考 -- Snapshot Restore

一、题目 备份集群下的索引 task&#xff0c;存储快照名称为 snapshot_1 二、思考 这个涉及的是集群的备份&#xff0c;主要是通过创建快照&#xff0c;涉及到以下2步骤 Setp1&#xff1a;注册一个备份 snapshot repository Setp2&#xff1a;创建 snapshot 可以通过两种方…

找生网站方案———未来之窗行业应用跨平台架构

1&#xff09;网站设计方面的考虑 主色调采用于公司深蓝色颜色&#xff0c;网页整体色彩明快、大气、简洁&#xff0c;每个细节均经过精心处 理&#xff0c;网页浏览快速&#xff0c;导航明确清晰。 网页设计要充分考虑网页的整体感觉&#xff0c;每个页面的图片与网站色调的过…

YOLO11改进 | 卷积模块 | 用Ghost卷积轻量化网络【详细步骤】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; Ghost 模块可以作为即插即用组件来升级…

C(十四)while、for、do-while循环综合(一)

uu们&#xff0c;小弟我本科在读&#xff0c;文章我会一直坚持更新下去&#xff0c;包括但不限于C初阶、C进阶、数据结构、C、Linux、MySQL、项目、QT开发、各种算法&#xff08;之后会持续更新&#xff09;&#xff0c;并且站在小白的视角尽可能通俗易懂地把这些写出来&#x…

xss之dom类型

目录 xss关于dom类型 1、闭合方式 2、闭合&#xff0c;直接输入1&#xff0c;成功闭合 上我们的pikachu xss关于dom类型 1、闭合方式 输入123&#xff0c;然后打开f12&#xff0c;审查元素&#xff0c;之前一直没有搞懂为什么要在前面加上个单引号 输入两个双引号&#x…