扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
为了熟悉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当用户要申请一块内存时,堆分配算法将遍历整个链表,直到找到一块足够大的空闲块,
如果这个空闲块小于申请大小的两倍,那么直接将这个空闲块标记为占用块,然后将它的地址返回给用户;
如果空闲块大小大于所申请的大小这个空闲块大于申请大小的两倍),那么这个空闲块将被分割成两块,
其中一块大小为申请的大小,标记为占用,另外一块为空闲块.
4 字符串相关操作 string.c在传统的C语言和UNIX里面,IO和文件是同一个概念,所有的IO都是通过对文件的操作来实现的。因此,只要实现了文件的基本操作(
fopen、fread、fwrite、fclose和 fseek
),即是完成了Mini CRT的IO部分
5 格式化字符串 printf.c字符串相关的操作也是CRT的一部分,包括计算字符串长度、比较两个字符串、整数与字符串之间的转换等。由于这部分功能无须涉及任何与内核交互,是纯粹的用户态的计算,所以它们的实现相对比较简单。
MiniCRT 使用说明
printf
是一个典型的变长参数函数,即参数数量不确定实现的相关内容列举如下:
printf
实现仅支持%d
、%s
,且不支持格式控制(比如%08d
)。- 实现
fprintf
和vfprintf
,实际上printf
是fprintf
的特殊形式,即目标文件为标准输出的fprintf
。- 实现与文件字符串操作相关的几个函数,
fputc
和fputs
。
Mini CRT将以库文件和头文件的形式提供给用户。我们建立的minicrt.h
的头文件,包含了所有相关的常数定义、宏定义,以及Mini CRT所实现的函数声明等。当用户程序使用Mini CRT 时,仅需要#include "minicrt.h"
即可,而无须像标准的CRT一样,需要独立的包含相关文件,比如stdio.h
、stdlib.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会把strlen
、strcmp
等这些常用函数展开成它内部的实现。-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元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流