crt linux版_跟我学c++中级篇——Linux下的动态库之五运行库

2e4bb1a4277715abae19d0280a42bd15.png

一、什么是运行库

在前面学习了动态库的编写和分析,在实际的工作中,可能会发现,其实很多函数或者说API已经以动态库或者静态库的方式提供了出来,程序员只要包含相关的头文件,或者安装相关的库即可使用。而这些库,就可以称为运行时库,也就是CRT。
有了运行库的支持,再进行编程,就有些类似于站在巨人的肩膀上,不用自己再频繁的重复的创建轮子,只要把基础的零件一拼(接口调用)就可以实现相应的程序功能。一个标准的C/C++的运行库一般要实现如下的功能:
1、引导应用程序的启动和退出:加载和初始化相关的入口函数及相关依赖。
2、基础应用接口:即C/C++标准定义的相关基础接口函数。
3、相关OS的IO功能:和OS相关的IO实现。
4、内存的管理:堆、栈等的设计和实现。
5、语言形式化实现:包括一些特定的要求、功能,比如模板。
6、调试和检验:针对内存越界和指针判断等的调试功能和验证功能。
7、其它:如一些特定的宏等的设计

二、C/C++的运行库

正如以前学习所知一样,目前的主流平台主要包括GLIBC和MSVCRT两个运行库。
1、glibc
glibc库如果在LINUX平台上进行过编程的,应该都比较清楚,lib,lib64,/usr/lib,/usr/lib64这几个位置是默认的位置。需要注意的是,/usr/local/lib,/usr/local/lib64不是默认的位置。glibc的启动文件和前面的分析一样,有一个_start函数,调用__libc_start_main。然后在这个函数里调用_init(),完成一些全局、静态变量的初始化。同时注册__finit等函数,准备销毁时的调用。
这就不得不提到相应的crt1.o, crti.o, crtbegin.o, crtend.o, crtn.o,这些文件是为了提供辅助的初始化工作等,这些都可以在相关的目录下找到,如果在自己的系统中位置中找不到,可以使用find命令搜索一下,不同的系统可能安装有细微的区别。
一般来说,有静态库也会提供动态库的使用,这个有兴趣可以看看,不过不同的版本的差异还是要分清楚。
2、msvcrt
微软的东西有一个特点,大包大揽,分的又特别的细,使用过VS的就知道有Debug版,有Release版,同时又分多线程版,单线程(这个在03后就废弃)。静态动态版。这样的话,区分不同的库就可以使用不两只的标记来查询:
比如d,表示调试版,mt表示多线程。但是在MSVCRT中有一个特点,就是即使是动态库也有一个.lib文件,msvcrt提供了C和C++两个版本的库。以命名中有没有p来区别,比如libcpmtd1.lib。
但是这里埋了雷啊,不同的版本太多,导致在开发和部署时,经常用错了库,如果库少,还是比较好定位的,如果库多,还真是有点小麻烦,特别是库调用库的,还是真得挺麻烦。

3、多线程
多线程其实最初只是存在于Windows,在LINUX是轻量级进程,不过后来POSIX也提供了pthread.线程的优点不说,只说线程一般要求自己的资源也要能够独立控制,这样就需要线程处理相关的私有数据的方式。最常见的就是在前面分析过的TLS,线程局部存储,有兴趣可以翻翻前面的分析,学习一下。
另外需要注意的是,在c++11提供了std::thread的支持,这样就基本了打通了平台之间复杂性,掌握一个,也就掌握了多个平台。
4、IO
其实这个如果在LINUX平台上非常好理解,在LINUX平台上一切皆文件,这就形成一种局部,所以有的操作其实都read,write,不同的版本或者不同的库可能名字略有不同,支持的读写方式略有不同而已。比如在新老版本中可能读的名字一个叫fread,另外一个叫fread_s,但最终调用的基本都是一个函数。
5、内存管理
最主要的其实就是堆和栈,不同的平台堆和栈实现的细节可能有所不同,但原理都是一样的。栈是由系统来管理的内存,而堆是由程序员自己控制的内存。而在运行库里就是要实现这两种内存分配的支持。如果学过汇编语言,可能对栈理解就会非常清晰,其实可以把它当作一个后进先出的盒子,最上面的永远是最后进来的,但是却最先出去。栈一般比较小,一般是以M为单位,虽然平台上都可以调整,但都会推荐调整的范围不会太大。
堆有点复杂,堆是用来向程序提供巨大空间内存的。一般来说,不管C和C++,内存最终都会调用malloc这个函数来分配内存,而这个函数又会调用OS的底层不同的内存分配接口来实现内存的创建。在Windows平台上,一个进程可能会有多个堆,堆的地址在虚拟地址空间上是连续的,但在物理地址上,可能由于映射的不同,会不连续。
malloc会调用brk(),mmap()用来分配空间,而Windows上则使用VirtualAlloc这个函数调用来实现。这里有一点需要明白,在调用malloc第一次时,一定会调用底层API,但是如果调用功后再调用,可能就未必了,因为malloc可能批发的内存会有结余。结余够的情况下,就不不再调用API了,否则仍然会。

三、总结

运行库其实就是统一标准、方便开发的一个环境,只不过以运行库提供,让整个系统会更便捷安全,整体最优。所以到现在为止就可以明白,动态库的优势了,但是在这篇文章中发现,运行库中不但有动态库,其实静态库更多,所以下来就会学习静态库的编程。

57a1711c2f96c88e42290eef0f66888b.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值