zoukankan      html  css  js  c++  java
  • 【转】C RunTime Library 暨 深入理解编译选项的含义 01

    以下内容来源于网络,作者不明。

    一 产生

     
    运行时库是程序在运行时所需要的库文件,通常以LIB或DLL形式提供。
     
    C运行时库就是C run-time library,诞生于20世纪70年代,是C而非C++语言世界的概念,C程序运行时需要这些库中的函数。
     
    C 语言是所谓的“小内核”语言,就其语言本身来说很小(不多的关键字,程序流程控制,数据类型等)。所以,C语言内核开发出来之后,Dennis Ritchie和Brian Kernighan就用C本身重写了90%以上的UNIX系统函数,并且把其中最常用的部分独立出来,形成头文件和对应的LIBRARY,C运行时库就是这样形成的。
     
    随着C语言的流行,各个C编译器的生产商/个体/团体都遵循老的传统,在不同平台上都有相对应的Standard Library,但大部分实现都是与各个平台有关的。由于各个C编译器对C的支持和理解有很多分歧和微妙的差别,所以就有了ANSI C;ANSI C(主观意图上)详细的规定了C语言各个要素的具体含义和编译器实现要求,引进了新的函数声明方式,同时订立了Standard Library的标准形式。所以C运行时库由编译器生产商提供。至于由其他厂商/个人/团体提供的头文件和库函数,应当称为第三方C运行库(Third party C run-time libraries)。
     
    二 发展
     
    到了 C++ 世界里,有另外一个概念:Standard C++ Library,它包括了上面所说的 C run-time library 和 STL。包含 C run-time library 的原因很明显,C++ 是 C 的超集,没有理由再重新来一个 C++ run-time library. VC针对C++ 加入的Standard C++ Library主要包括:LIBCP.LIB, LIBCPMT.LIB和 MSVCPRT.LIB
     
    C运行库刚诞生的时候,程序世界还很单纯,应用程序都是单线程的,多任务或多线程机制在此时还属于新观念。所以这个时期的C运行时库都是单线程的。
     
    随着操作系统多线程技术的发展,最初的C运行时库无法满足程序的需求,出现了严重的问题。C运行时库使用了多个全局变量(例如errno)和静态变量,这可能在多线程程序中引起冲突。假设两个线程都同时设置errno,其结果是后设置的errno会将先前的覆盖,用户得不到正确的错误信息。
     
    因此,Visual C++提供了两种版本的C运行时库。一个版本供单线程应用程序调用,另一个版本供多线程应用程序调用。多线程运行时库与单线程运行时库有两个重大差别:
     
    (1)类似errno的全局变量,每个线程单独设置一个。这样从每个线程中可以获取正确的错误信息。
     
    (2)多线程库中的数据结构以同步机制加以保护。     这样可以避免访问时候的冲突。
     
    Visual C++提供的多线程运行时库又分为静态链接库和动态链接库两类,而每一类运行时库又可再分为debug版和release版,因此Visual C++共提供了6个运行时库。如下表:(单线程和多线程都有debug版和release版;只有多线程才有静态链接库和动态链接库之分)
     
    C运行时库 库文件
    Single thread(static link) libc.lib
    Debug single thread(static link) libcd.lib
    MultiThread(static link) libcmt.lib
    Debug multiThread(static link) libcmtd.lib
    MultiThread(dynamic link) msvcrt.lib(导入库)
    Debug multiThread(dynamic link) msvcrtd.lib(导入库)
     
    三 C运行库的作用
     
    (1)C运行时库包含了C程序运行的最基本和最常用的函数(如memcpy、printf、malloc等)。
    (2)C运行时库除了给我们提供必要的库函数调用之外,它提供的另一个最重要的功能是为应用程序添加启动函数。C运行时库启动函数的主要功能为进行程序的初始化,对全局变量进行赋初值,加载用户程序的入口函数。
     
    不采用宽字符集的控制台程序的入口点为mainCRTStartup(void)。下面我们以该函数为例来分析运行时库究竟为我们添加了怎样的入口程序。这个函数在crt0.c中被定义,下列的代码经过了笔者的整理和简化:
     
    void mainCRTStartup(void)
    {
    int mainret;
    /*获得WIN32完整的版本信息*/
    _osver 
    = GetVersion();
    _winminor 
    = (_osver >>  & 0x00FF ;
    _winmajor 
    = _osver & 0x00FF ;
    _winver 
    = (_winmajor <<  + _winminor;
    _osver 
    = (_osver >> 16& 0x00FFFF ;
    _ioinit(); 
    /* initialize lowio */
     
    _acmdln 
    = (char *) GetCommandLineA(); /* 获得命令行信息 */
    _aenvptr 
    = (char *) __crtGetEnvironmentStringsA(); /* 获得环境信息 */
    _setargv(); 
    /* 设置命令行参数 */
    _setenvp(); 
    /* 设置环境参数 */
    _cinit(); 
    /* C数据初始化:全局变量初始化,就在这里!*/
    __initenv 
    = _environ;
    mainret 
    = main( __argc, __argv, _environ ); /*调用main函数*/
    exit( mainret );
    }
     
    从以上代码可知,运行库在调用用户程序的main或WinMain函数之前,进行了一些初始化工作。初始化完成后,接着才调用了我们编写的main或WinMain函数。只有这样,我们的C语言运行时库和应用程序才能正常地工作起来。
     
    你写的程序可以没有math库,程序照样运行,只是不能处理复杂的数学运算,不过如果没有了C run-time库,main()就不会被调用,exit()也不能被响应。
     
    除了crt0.c外,C运行时库中还包含wcrt0.c、 wincrt0.c、wwincrt0.c三个文件用来提供初始化函数。wcrt0.c是crt0.c的宽字符集版,wincrt0.c中包含windows应用程序的入口函数,而wwincrt0.c则是wincrt0.c的宽字符集版。
     
    Visual C++的运行时库源代码缺省情况下不被安装。如果您想查看其源代码,则需要重装Visual C++,并在重装在时选中安装运行库源代码选项。
  • 相关阅读:
    Python开发环境Spyder介绍
    Python干货整理之数据结构篇
    通过Python爬虫按关键词抓取相关的新闻
    疫情后来场说走就走的旅行,Python制作一份可视化的旅行攻略
    详细介绍去一年在 PyPI 上下载次数最多的 Python 包
    Python错误与异常
    python爬虫爬取2020年中国大学排名
    微信史上最短的一行功能代码:拍一拍
    Python爬取某宝商品数据案例:100页的价格、购买人数等数据
    我的SAS菜鸟之路7
  • 原文地址:https://www.cnblogs.com/mumuliang/p/2064830.html
Copyright © 2011-2022 走看看