【Linux】库制作与原理

库制作与原理



一、什么是库

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


预备工作,准备好历史封装的libc代码,在任意新增“库文件”

代码如下(示例):

// my_stdio.h
#pragma once
#define SIZE 1024
#define FLUSH_NONE 0
#define FLUSH_LINE 1
#define FLUSH_FULL 2
struct IO_FILE
{
int flag; // 刷新⽅式
int fileno; // ⽂件描述符
char outbuffer[SIZE];
int cap;
int size;
// TODO
};
typedef struct IO_FILE mFILE;
mFILE *mfopen(const char *filename, const char *mode);
int mfwrite(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 <sys/types.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(mode, "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 = SIZE;
return mf;
}
void mfflush(mFILE *stream)
{
if(stream->size > 0)
{
// 写到内核⽂件的⽂件缓冲区中!
write(stream->fileno, stream->outbuffer, stream->size);
// 刷新到外设
fsync(stream->fileno);
stream->size = 0;
}
}
int mfwrite(const void *ptr, int num, mFILE *stream)
{
// 1. 拷⻉
memcpy(stream->outbuffer+stream->size, ptr, num);
stream->size += num;
// 2. 检测是否要刷新
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 once
int 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;
}

四个总结

在这里插入图片描述


二、静态库

在这里插入图片描述

2.1 静态库生成

在这里插入图片描述
在这里插入图片描述


2.2 静态库使用

在这里插入图片描述


三、动态库

在这里插入图片描述

3.1 动态库生成

在这里插入图片描述
在这里插入图片描述


3.2 动态库使用

在这里插入图片描述


3.3 库运行搜索路径

在这里插入图片描述


五、目标文件

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


六、ELF文件

在这里插入图片描述
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述


七、ELF从形成到加载轮廓

7.1 ELF形成可执行

在这里插入图片描述
在这里插入图片描述
注意:实际合并是在链接时进行的,但是并不是这么简单的合并,也会
涉及对库的合并!


7.2 ELF可执行文件加载

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


八、理解链接与加载

8.1 静态链接

在这里插入图片描述
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述


8.2 ELF加载与进程地址空间

8.2.1 虚拟地址/逻辑地址

在这里插入图片描述


8.2.2 重新理解进程虚拟地址空间

ELF在被编译好之后,会把自己未来程序的入口地址记录在
ELF header的Entry字段中


8.3 动态链接与动态库加载

8.3.1 进程如何看到动态库

在这里插入图片描述


8.3.2 进程间如何共享库

在这里插入图片描述


8.3.3 动态链接

8.3.3.1 概要

在这里插入图片描述


8.3.3.2 我们的可执行程序被编译器动了手脚

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


8.3.3.3 动态库中的相对地址

在这里插入图片描述


8.3.3.4 我们的程序怎么和库具体映射起来的

在这里插入图片描述


8-3-3-5 我们的程序,怎么进⾏库函数调⽤

在这里插入图片描述


8-3-3-6 全局偏移量表GOT(global offset table)

在这里插入图片描述


在这里插入图片描述


8-3-3-7 库间依赖

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述


8.3.4 总结

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值