实现简略版C/C++RuntimeLibrary(MiniCRT)-创新互联

实现简略版 C/C++ Runtime Library(Mini CRT) 一、意义

为了熟悉C/C++语言特性,了解底层知识,总结《程序员的自我修养–链接、装载与库》内容

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:国际域名空间、虚拟空间、营销软件、网站建设、化德网站维护、网站推广。二、参考资料

《程序员的自我修养–链接、装载与库》

github git@github.com:youzhonghui/MiniCRT.git

【C++】【笔记】实现32位简单版Windows和Linux双平台的C++运行库

三、实现 目录结构

在这里插入图片描述

通常我们会把CRT的各个函数的声明放在不同的头文件中,比如 IO相关的位于stdio.h;字符串和堆相关的放在stdlib.h中。为了简单起见,将Mini CRT中所有函数的声明都放在minicrt.h中。

功能概述

CRT支持Linux和Windows两个平台,功能包括

  • 入口函数功能 entry.c

  • 堆管理 malloc.c

  • 基本IO stdio.c

  • 字符串操作 string.c

  • 打印显示 printf.c

代码小技巧

支持两个平台

#ifdef WIN32
//Windows 平台demo

#else
//Linux 平台demo
#endif

支持C和C++

#ifdef  __cplusplus
extern "C" {#endif

………………………………
 
#ifdef  __cplusplus
}
#endif
功能详解 1 入口函数功能 entry.c void mini_crt_entry(void)

在这里插入图片描述

2 堆管理 malloc.c

使用双向链表管理堆空间

typedef struct _heap_header
{enum{  HEAP_BLOCK_FREE = 0XABABABAB,
      HEAP_BLOCK_USED = 0XCDCDCDCD
  }type;
    unsigned long size;
    struct _heap_header* next;
    struct _heap_header* prev; 
}heap_header;

void free(void* ptr)

当用户释放某一块空间时,堆分配算法会判别被释放块前后两个块是否为空闲块,

如果是,则将它们合并成一个大的空闲块。

void* malloc(unsigned long size)

当用户要申请一块内存时,堆分配算法将遍历整个链表,直到找到一块足够大的空闲块,

如果这个空闲块小于申请大小的两倍,那么直接将这个空闲块标记为占用块,然后将它的地址返回给用户;

如果空闲块大小大于所申请的大小这个空闲块大于申请大小的两倍),那么这个空闲块将被分割成两块,

其中一块大小为申请的大小,标记为占用,另外一块为空闲块.

3 IO与文件操作 stdio.c

在传统的C语言和UNIX里面,IO和文件是同一个概念,所有的IO都是通过对文件的操作来实现的。因此,只要实现了文件的基本操作(fopen、fread、fwrite、fclose和 fseek),即是完成了Mini CRT的IO部分

4 字符串相关操作 string.c

字符串相关的操作也是CRT的一部分,包括计算字符串长度、比较两个字符串、整数与字符串之间的转换等。由于这部分功能无须涉及任何与内核交互,是纯粹的用户态的计算,所以它们的实现相对比较简单。

5 格式化字符串 printf.c

printf是一个典型的变长参数函数,即参数数量不确定

实现的相关内容列举如下:

  • printf实现仅支持%d%s,且不支持格式控制(比如%08d)。
  • 实现fprintfvfprintf,实际上printffprintf的特殊形式,即目标文件为标准输出的fprintf
  • 实现与文件字符串操作相关的几个函数,fputcfputs
MiniCRT 使用说明

Mini CRT将以库文件和头文件的形式提供给用户。我们建立的minicrt.h的头文件,包含了所有相关的常数定义、宏定义,以及Mini CRT所实现的函数声明等。当用户程序使用Mini CRT 时,仅需要#include "minicrt.h"即可,而无须像标准的CRT一样,需要独立的包含相关文件,比如stdio.hstdlib.h等。

1 用户程序中引用头文件 #include “minicrt.h”

2 将MiniCRT程序编译成库文件,由于动态库的实现比静态库要复杂,所以MiniCRT仅仅以静态库的形式提供给最终用户。

在Linux中 使用命令

gcc -c -fno-builtin -nostdlib -fno-stack-protector -m64 entry.c malloc.c stdio.c string.c printf.c ar -rs minicrt.a malloc.o printf.o stdio.o string.o

  • 这里的-fno-builtin参数是指关闭GCC的内置函数功能,默认情况下GCC会把strlenstrcmp等这些常用函数展开成它内部的实现。
  • -nostdlib表示不使用任何来自glibc、GCC的库文件和启动文件,它包含了-nostartfiles这个参数。
  • -fno-stack-protector是指关闭堆栈保护功能,最近版本的GCC会在vfprintf这样的变长参数函数中插入堆栈保护函数,如果不关闭,我们在使用Mini CRT时会发生“stack chk fail”函数未定义的错误。

3 将用户程序预处理、编译、汇编成二进制文件

在Linux中 使用命令

gcc -c -ggdb -fno-builtin -nostdlib -fno-stack-protector -m64 test.c

4 二进制文件链接静态库,生成可执行文件

ld -static -m elf_x86_64 -e mini_crt_entry entry.o test.o minicrt.a -o test

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


标题名称:实现简略版C/C++RuntimeLibrary(MiniCRT)-创新互联
文章出自:http://azwzsj.com/article/csihdg.html