库的制作与原理(一)
·1.库的概念
库是写好的,现成的可以复用的代码。本质上库是一种可执行的二进制形式,可以被操作系统载入内存执行。库有俩种:静态库 .a[Linux] .lib[windows] 动态库 .so[Linux] .dll[windows]
就是把.c文件变成.o文件,把许多的.o文件一起打包成.a或者.so。


需要用到的代码
my_stdio.h
#pragma once
#define SIZE 1024#define FLUSH_NONE 0
#define FLUSH_LINE 1
#define FLUSH_FULL 2struct IO_FILE
{int flag;//刷新方式int fileno;//文件描述符char outbuffer[SIZE];int cap;int size;
};typedef struct IO_FILE mFILE;mFILE* mfopen(const char* filename,const char* mode);
int mfwirte(const void* ptr,int num,mFILE* stream);
void mfflush(mFILE* stream);
void mfclose(mFILE* stream);
my_stdio.c
#include"my_stdio.h"
#include<string.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>mFILE* mfopen(const char* filename,const char* mode)
{int fd=-1;if(strcmp(mode,"r")==0){fd=open(filename,O_RDONLY);}else if(strcmp(mpde,"w")==0){fd=open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);}else if(strcmp(mode,"a")==0){fd=open(filename,O_CREAT|O_WRONLY|O_APPEND,0666);}if(fd<0){return NULL;}mFILE* mf=(mFILE*)malloc(sizeof(mFILE));if(!mf){close(fd);return NULL;}mf->fileno=fd;mf->flag=FLUSH_LINE;mf->size=0;mf->cap;return mf;}void mfflush(mFILE* stream)
{if(stream->size>0){//写到内核文件的缓冲区中write(stream->fileno,steam->outbuffer,stream->size);//用fsync函数稳定刷新到外设fsync(stream->fileno);stream->size=0;}}int mfwrite(const void* ptr,int num,mFILE* stream)
{memcpy(stream->outbuffer+stream,ptr,num);stream->size+=num;//检查是否更新if(stream->flag==FLUSH_LINE&&stream->size>0&&stream->outbuffer[stream->size-1]=='\n'){mfflush(stream);}return num;}void mfclose(mFILE* stream)
{if(stream->size>0){mfflush(stream);}close(stream->fileno);}
my_string.h
#pragma onceint my_strlen(const char* s);
my_string.c
#include"my_string.h"int my_strlen(const char* s)
{const char* end=s;while(*end!='\0')end++;return end-s;
}
fsync函数是 POSIX 标准中定义的一个函数,用于将文件描述符指向的文件的数据强制写入到磁盘上。这个函数确保了所有缓冲区中的数据都被写入到磁盘,并且磁盘上的数据是最新的。这对于需要确保数据持久化的应用场景非常重要,例如数据库、日志文件等。
2.静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中,程序运行时将不再需要静态库。
一个可执行程序可能用到许多库,这些库运行有的是静态库,有的是动态库,而我们编译默认认为动态链接库,只有在该库找不到动态.so的时候才会采用同名静态库。可以使用gcc的-static强转设置链接静态库。
静态库的生成
makefile文件
libmystdio.a:my_stdio.o my_string.o@ar -rc $@ $^@echo "bulid $^ to $@"%.o:%.c@gcc -c $<@echo "compling $< to $@".PHONY:clean
clean:@rm -rf *.a *.o stdc*.PHONY:output
output:@mkdir -p stdc/include@mkdir -p stdc/lib@cp -f *.h stdc/include@cp -f *.a stdc/lib@tar -czf stdc.tgz stdc
ar是gun归档工具,rc表示replace and create

静态库的使用
#include "my_stdio.h"
#include "my_string.h"
#include <stdio.h>
int main()
{const char *s = "abcdefg";printf("%s: %d\n", s, my_strlen(s));mFILE *fp = mfopen("./log.txt", "a");if(fp == NULL) return 1;mfwrite(s, my_strlen(s), fp);mfwrite(s, my_strlen(s), fp);mfwrite(s, my_strlen(s), fp);mfclose(fp);return 0;
}
~
场景一:头文件和库文件安装到系统默认路径下时
指令:gcc main.c -lmystdio
场景二:头文件和库文件和源文件在同一路径下时
指令:gcc main.c -L. -lmymath
场景三:头文件和库文件有自己的独立路径
gcc main.c -I头文件路径 -L库文件路径 -lmymath(链接库的名称)
注意:库的名称要去掉前面的lib和后缀才是名字


3.动态库
动态库(.so):程序在运行时的时候才去链接动态库的代码,多个程序共享使用库的代码。
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机械码。
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间,操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有1进程共享,节省了内存和磁盘空间。
动态库的生成
libmystdio.so:my_stdio.o my_string.o@gcc -o $@ $^ -shared@echo "bulid $^ to $@"%.o:%.c@gcc -fPIC -c $<@echo "compling $< to $@".PHONY:clean
clean:@rm -rf *.so *.o stdc*.PHONY:output
output:@mkdir -p stdc/include@mkdir -p stdc/lib@cp -f *.h stdc/include@cp -f *.so stdc/lib@tar -czf stdc.tgz stdc
shared:表示生成共享库格式
fPIC:产生位置无关码(position independent code)
库名规则:libxxx.so
动态库使用
场景一:头文件和库文件安装到标准系统路径下
gcc main.c -lmystdio
场景二:头文件和库文件与源文件在同一个路径下
gcc main.c -L. -lmymath
场景三:头文件和库文件都有自己的独立路径
gcc main.c -I头文件路径 -L库文件路径 -lmymath



4.库运行搜索路径
问题:
按照指令却显示问题,是因为链接器没有正确找到库文件的路径
![]()
解决方案
拷贝.so文件到系统共享库路径下,一般指/user/lib,或者指明完整库路径,例如拷贝到/lib64路径下
先系统共享路径下建立软连接,在/lib64下建立一个与库文件的软连接,先找到软连接再找到库
更改环境变量:LD_LIBRARY_PATH,这个通常是空的,OS运行程序,要查找动静态库,也会在该环境变量, 把完整库的路径赋值给这个环境变量
ldconfig方案:配置/etc/ld.so.conf.d/,ldconfig更新 ,这个路径系统会提前准备打开,把库路径放进去就会1提前准备好,在/etc/ld.so.conf.d/路径下配置好文件还要ldconfig更新一下。
5.目标文件
编译和链接这俩个步骤,在windows下被IDE封装的很完美。

编译的过程:将程序的源代码翻译成CPU能够直接运行的机器代码。
为什么要有目标文件?假如有多个原文件,直接就合在一起编译,要是其中有一个要修改,则又要重新全部在和一起就浪费效率了,而每个都形成目标文件,改了一个也只要单独编译这一个,不影响其它。目标文件是一个二进制文件,文件的格式是ELF,是对二进制代码的一种封装。

6.ELF文件
以下四种文件都是ELF文件:
可重定位位文件:xxx.o文件
可执行文件
共享目标文件:xxx.so文件
内核转储
一个ELF文件由以下四部分组成:
ELF头:描述文件的主要特性。位于文件的开始位置,主要目的是定位文件的其它部分。
程序头表:列举了所有有效的段和它们的属性。表里记着每个段的开始位置和位移,长度,因为放在二进制文件中,需要段表的描述信息才能把它们每个段分隔开。
节头表:包含对节的描述
节:ELF文件中的基本组成单位,包含了特定类型的数据,ELF文件的各种学习和数据存储在不同的节中,如代码节存储了可执行代码,数据节存储了全局变量和静态数据等。
最常见的节:
代码节(.text) 数据节(.data)

相关文章:
库的制作与原理(一)
1.库的概念 库是写好的,现成的可以复用的代码。本质上库是一种可执行的二进制形式,可以被操作系统载入内存执行。库有俩种:静态库 .a[Linux] .lib[windows] 动态库 .so[Linux] .dll[windows] 就是把.c文件变成.o文件,把…...
go 日志框架
内置log import ("log""os" )func main() {// 设置loglog.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)// 自定义日志前缀log.SetPrefix("[pprof]")log.Println("main ..")// 如果用format就用PrintF,而不是…...
JavaScript 最佳实践
我只选取了我还没完全贯彻的条目罗列如下. 1.函数命名 函数名由动词开头,如getName(); 2.布尔类型命名 若函数返回布尔值,则函数名以is/can等开头. 3.常量命名约定 常量名全大写并以下划线""连接. 4.变量类型透明化 定义变量时,应将其立即初使化为一个与其同类型…...
Rust配置笔记
1.Node.js下载配置 2.c环境配置 C我是用vs装的点击这个installer 点击修改 选择C环境就行,这个时候它就帮忙配置环境了 3.Rust下载配置 4.装napi-rs框架 npm install -g napi-rs/cliRust下载网站 下完之后直接打开 一开始下包会比较慢,多等等 下好之后跑项目前第一件事配置…...
大模型WebUI:Gradio全解12——LangChain原理及agents构建Gradio UI(1)
大模型WebUI:Gradio全解12——LangChain原理及agents构建Gradio UI(1) 前言本篇摘要12. LangChain原理及其agent构建Gradio UI12.1 LangChain介绍12.1.1 概念12.1.2 用途12.1.3 文档参考文献前言 本系列文章主要介绍WEB界面工具Gradio。Gradio是Hugging Face发布的简易WebU…...
具有整合各亚专科医学领域知识能力的AI智能体开发纲要(2025版)
整合各亚专科医学领域知识能力的AI代理的开发与研究 一、引言 1.1 研究背景 在科技飞速发展的当下,人工智能(AI)已成为推动各行业变革的关键力量,医疗领域也不例外。近年来,AI 在医疗行业的应用取得了显著进展,从医学影像诊断到疾病预测,从药物研发到个性化医疗,AI 技…...
机器学习在脑卒中预测中的应用:不平衡数据集处理方法详解
机器学习在脑卒中预测中的应用:不平衡数据集处理方法详解 目录 引言 脑卒中的全球影响机器学习在医疗预测中的挑战类别不平衡问题的核心痛点数据预处理与特征选择 数据来源与清洗缺失值处理方法类别特征编码特征选择技术处理类别不平衡的四大方法 SMOTE(合成少数类过采样技术…...
数据表的存储过程和函数介绍
文章目录 一、概述二、创建存储过程三、在创建过程中使用变量四、光标的使用五、流程控制的使用六、查看和删除存储过程 一、概述 存储过程和函数是在数据库中定义的一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句。存储过程和函数可…...
为AI聊天工具添加一个知识系统 之117 详细设计之58 思维导图及观察者效应 之2 概念全景图
(说明:本文和上一篇问题基本相同,但换了一个模型 deepseek-r1) Q1227、在提出项目“为使用AI聊天工具的聊天者加挂一个专属的知识系统”后,我们已经进行了了大量的讨论-持续了近三个月了。这些讨论整体淋漓尽致体现了…...
Error [ERR_REQUIRE_ESM]: require() of ES Module
报错信息: 【报错】Message.js 导入方式不对,用的是 ES Moudle 的语法,提示使用 import 引入文件 项目开发没有用到 js-message 依赖,是 node-ipc 依赖中用到的 js-message 依赖, node-ipc 中限制 js-message 版本&a…...
GStreamer源码安装1.24版本
从官网下载 1.24的源码包 https://gitlab.freedesktop.org/gstreamer/gstreamer/-/tree/1.24?ref_typeheads#getting-started ,尝试过使用git clone 的方式,但速度贼慢,就选择了下载源码包的方式安装依赖 sudo apt install libssl-dev g me…...
从CNN到Transformer:遥感影像目标检测的未来趋势
文章目录 前言专题一、深度卷积网络知识专题二、PyTorch应用与实践(遥感图像场景分类)专题三、卷积神经网络实践与遥感影像目标检测专题四、卷积神经网络的遥感影像目标检测任务案例【FasterRCNN】专题五、Transformer与遥感影像目标检测专题六、Transfo…...
从 x86 到 ARM64:CPU 架构的进化与未来
在计算机发展的历史长河中,x86、x64 和 ARM64 这三大主流 CPU 架构各自书写了辉煌的篇章。它们不仅代表了技术的进步,更承载着无数创新者的梦想与努力。 x86:从 16 位到 32 位的辉煌之路 诞生与崛起 1978 年,英特尔(…...
Java数据结构第十二期:走进二叉树的奇妙世界(一)
专栏:数据结构(Java版) 个人主页:手握风云 目录 一、树型结构 1.1. 树的定义 1.2. 树的基本概念 1.3. 树的表示形式 二、二叉树 2.1. 概念 2.2. 两种特殊的二叉树 2.3. 二叉树的性质 2.4. 二叉树的存储 三、二叉树的基本操作 一、树型结构 1.…...
基于ffmpeg+openGL ES实现的视频编辑工具-添加贴纸(八)
在当下丰富多元的音视频编辑应用领域,添加贴纸已然成为一项广受欢迎的功能,它能够为音视频作品注入独特的趣味与创意元素。本文将深入探究音视频添加贴纸背后所涉及的技术原理与实现路径。 一、技术原理概述 音视频从本质上来说,是由一系列连续的图像帧(针对视频部分)以…...
【AI时代】基于AnythingLLM+ Ollama + DeepSeek 搭建本地知识库
一、本地安装Ollama及DeepSeek 参考教程: https://blog.csdn.net/Bjxhub/article/details/145536134 二、下载并安装AnythingLLM AnythingLLM下载地址: https://anythingllm.com/ 傻瓜式安装即可 可以自定义安装路径。三、配置AnythingLLM并使用 3.…...
leetcode刷题记录(一百一十五)——64. 最小路径和
(一)问题描述 64. 最小路径和 - 力扣(LeetCode)64. 最小路径和 - 给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下…...
UE5 编辑器辅助/加强 插件搜集
1. Actor Locker 地址:https://www.fab.com/listings/ec26ac5e-4720-467c-a3a6-b5103b6b74d0 使用说明:https://github.com/Gradess2019/ActorLocker 支持:5.0 – 5.5 简单的编辑器扩展。它允许你通过世界轮廓窗口/热键/上下文菜单在编辑器视…...
怎么在Github上readme文件里面怎么插入图片?
环境: Github 问题描述: 怎么在Github上readme文件里面怎么插入图片? https://github.com/latiaoge/AI-Sphere-Butler/tree/master 解决方案: 1.相对路径引用 上传图片到仓库 将图片文件(如 .png/.jpgÿ…...
什么是矩阵账号?如何高效运营tiktok矩阵账号
…...
SpringSecurity初始化的本质
一、对SpringSecurity初始化的几个疑问 通过前面第一次请求访问的分析我们明白了一个请求就来后的具体处理流程 对于一个请求到来后会通过FilterChainProxy来匹配一个对应的过滤器链来处理该请求。那么这里我们就有几个疑惑。 FilterChainProxy什么时候创建的?过滤器链和对应的…...
自注意力机制和CNN的区别
CNN:一种只能在固定感受野范围内进行关注的自注意力机制。CNN是自注意力的简化版本。自注意力:具有可学习感受野的CNN。自注意力是CNN的复杂形态,是更灵活的CNN,经过某些设计就可以变为CNN。 越灵活、越大的模型,需要…...
Vue 不同大版本与 Node.js 版本匹配的详细参数
Vue 2.x 与 Node.js 版本匹配: Vue 2.x 细分版本建议 Node.js 版本理由支持状态2.0 - 2.610.x - 14.x这些 Node.js 版本在 Vue 2.x 早期开发和维护阶段广泛使用,能提供稳定运行环境,适配当时常用构建工具和依赖包Node.js 10.x 维护期已结束;…...
本地部署DeepSeek-R1模型教程
文章目录 第一步:安装运行框架 哈喽各位小伙伴们,最近deepseek非常的火,不过因为全球访问量剧增经常会导致deepseek的服务器繁忙,如果想要稳定使用就得靠本地部署了,不仅可以稳定使用还能保护数据隐私,今天…...
设计心得——解耦的实现技术
一、说明 在前面的“设计心得——解耦”中,对解耦进行了高层次的抽象说明。本篇则对在实践中常用的解耦技术进行逐一分析说明,以期为开发者能更从理论到实践搭建一个桥梁。至于大家能够如何更好的在自己的项目中进行解耦的实践,就需要不断的…...
k2路由器登录校园网
教程1刷入Breed,并手动刷入Padavan固件:斐讯K1、K2、K2P 刷机、刷入Breed 辅助工具 | tb (tbvv.net) Padavan下载网址: 我用的是: Padavan 登录的网址是 192.168.123.1 Padavan配置教程: 先用网线连上校园网&#…...
基于Springboot学生宿舍水电信息管理系统【附源码】
基于Springboot学生宿舍水电信息管理系统 效果如下: 系统登陆页面 系统用户首页 用电信息页面 公告信息页面 管理员主页面 用水信息管理页面 公告信息页面 用户用电统计页面 研究背景 随着高校后勤管理信息化的不断推进,学生宿舍水电管理作为高校后勤…...
手机怎样玩电脑游戏?
如果您正在寻找一款能够实现手机远程控制电脑玩游戏的软件,本文推荐远程看看软件。这款软件不仅支持手机远程控制电脑,还具备电脑与电脑之间的多端互控功能,您能够随时随地畅玩游戏,享受无缝的游戏体验。此外,远程看看…...
【Linux网络】认识协议(TCP/UDP)、Mac/IP地址和端口号、网络字节序、socket套接字
⭐️个人主页:小羊 ⭐️所属专栏:Linux 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 1、初识协议2、UDP、TCP3、Mac、IP地址4、端口号5、网络字节序6、socket 1、初识协议 协议就是一种约定。如何让不同厂商生产的计…...
【软考知识】奇偶校验码,循环冗余码,海明码介绍
文章目录 **1. 奇偶校验码 (Parity Check Code)****基本原理****算法流程****优点与缺点****应用场景** **2. 循环冗余码 (Cyclic Redundancy Check, CRC)****基本原理****算法流程****例子****优点与缺点****应用场景** **3. 海明码 (Hamming Code)****基本原理****算法流程**…...
