1.概论

运行时库是程序在运行时所需要的库文件,通常运行时库是以LIB或DLL形式提供的。C运行时库诞生于20世纪70年代,当时的程序世界还很单纯,应用程序都是单线程的,多任务或多线程机制在此时还属于新观念。所以这个时期的C运行时库都是单线程的。

随着操作系统多线程技术的发展,最初的C运行时库无法满足程序的需求,出现了严重的问题。C运行时库使用了多个全局变量 (例如errno)和静态变量,这可能在多线程程序中引起冲突。假设两个线程都同时设置errno,其结果是后设置的errno会将先前的覆盖,用户得不 到正确的错误信息。

因此,Visual C++提供了两种版本的C运行时库。一个版本供单线程应用程序调用,另一个版本供多线程应用程序调用。多线程运行时库与单线程运行时库有两个重大差别:

(1)类似errno的全局变量,每个线程单独设置一个;

这样从每个线程中可以获取正确的错误信息。

(2)多线程库中的数据结构以同步机制加以保护。

这样可以避免访问时候的冲突。

Visual C++提供的多线程运行时库又分为静态链接库和动态链接库两类,而每一类运行时库又可再分为debug版和release版,因此Visual C++共提供了6个运行时库。如下表:
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) msvert.lib
Debug multiThread(dynamic link) msvertd.lib

2.C运行时库的作用

C运行时库除了给我们提供必要的库函数调用(如memcpy、printf、malloc等)之外,它提供的另一个最重要的功能是为应用程序添加启动函数。

C运行时库启动函数的主要功能为进行程序的初始化,对全局变量进行赋初值,加载用户程序的入口函数。

不采用宽字符集的控制台程序的入口点为mainCRTStartup(void)。下面我们以该函数为例来分析运行时库究竟为我们添加了怎样的入口程序。这个函数在crt0.c中被定义,下列的代码经过了笔者的整理和简化:
void mainCRTStartup(void)
{
int mainret;
/*获得WIN32完整的版本信息*/
_osver = GetVersion();
_winminor = (_osver >> 8) & 0x00FF ;
_winmajor = _osver & 0x00FF ;
_winver = (_winmajor << 8) + _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语言运行时库和应用程序才能正常地工作起来。

除了crt0.c外,C运行时库中还包含wcrt0.c、 wincrt0.c、wwincrt0.c三个文件用来提供初始化函数。wcrt0.c是crt0.c的宽字符集版,wincrt0.c中包含 windows应用程序的入口函数,而wwincrt0.c则是wincrt0.c的宽字符集版。

Visual C++的运行时库源代码缺省情况下不被安装。如果您想查看其源代码,则需要重装Visual C++,并在重装在时选中安装运行库源代码选项。

3.各种C运行时库的区别

(1)静态链接的单线程库

静态链接的单线程库只能用于单线程的应用程序,C运行时库的目标代码最终被编译在应用程序的二进制文件中。通过/ML编译选项可以设置Visual C++使用静态链接的单线程库。

(2)静态链接的多线程库

静态链接的多线程库的目标代码也最终被编译在应用程序的二进制文件中,但是它可以在多线程程序中使用。通过/MD编译选项可以设置Visual C++使用静态链接的单线程库。

(3)动态链接的运行时库

动态链接的运行时库将所有的C库函数保存在一个单独的动态链接库MSVCRTxx.DLL中,MSVCRTxx.DLL处理了多线程问题。使用/ML编译选项可以设置Visual C++使用动态链接的运行时库。

/MDd、 /MLd 或 /MTd 选项使用 Debug runtime library(调试版本的运行时刻函数库),与/MD、 /ML 或 /MT分别对应。Debug版本的 Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,加强了对错误的检测,因此在运行性能方面比不上Release版本。

下面看一个未正确使用C运行时库的控制台程序:
#include <stdio.h>
#include <afx.h>
int main()
{
CFile file;
CString str("I love you");
TRY
{
file.Open("file.dat",CFile::modeWrite | CFile::modeCreate);
}
CATCH( CFileException, e )
{
#ifdef _DEBUG
afxDump << "File could not be opened " << e->m_cause << "\n";
#endif
}
END_CATCH

file.Write(str,str.GetLength());
file.Close();
}

我们在"rebuild all"的时候发生了link错误:
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
main.exe : fatal error LNK1120: 2 unresolved externals
Error executing cl.exe.

发生错误的原因在于Visual C++对控制台程序默认使用单线程的静态链接库,而MFC中的CFile类已暗藏了多线程。我们只需要在Visual C++6.0中依次点选Project->Settings->C/C++菜单和选项,在Project Options里修改编译选项即可。

转载于:https://www.cnblogs.com/BeyondTechnology/archive/2011/03/27/1996724.html

Visual C++中的C运行时库浅析相关推荐

  1. 下一代VC运行时库——Universal CRT

    前言 其实the Universal CRT(通用C运行时库)已经不能算是"下一代",因为它已经在前两年伴随着Visual Studio 2015和Windows10发布.但是由于 ...

  2. 一文带你弄懂Visual Studio:运行时库及MT/MTD、MD/MDD

    一文带你弄懂Visual Studio:运行时库及MT/MTD.MD/MDD 引子 什么是Runtime Library? Runtime Library和运行库 MT MTD MD MDD的关系 静 ...

  3. 各个版本Microsoft Visual C++运行时库下载

    各个版本Microsoft Visual C++运行时库下载 Microsoft Visual C++ 2005 Microsoft Visual C++ 2005 Redistributable P ...

  4. /MD, /MDD, /ML, /MT,/MTD(使用运行时库)

    1. VC编译选项 多线程(/MT) 多线程调试(/MTd) 多线程 DLL (/MD) 多线程调试 DLL (/MDd) 2. C 运行时库                              ...

  5. /MD, /MDD, /ML, /MT,/MTD(使用运行时库) .

    1. VC编译选项 多线程(/MT) 多线程调试(/MTd) 多线程 DLL (/MD) 多线程调试 DLL (/MDd) 2. C 运行时库                              ...

  6. VC C运行时库(CRTL)的几个版本及选用

    VC C运行时库(CRTL)的几个版本及选用Michael 2006年7月27日于突尼斯 VC++ C运行时库(以下简称CRTL)是指LIBC.LIB/LIBCMT.LIB/MSVCRT.LIB以及他 ...

  7. C语言标准及C标准库、运行时库简介

    1.C语言标准: 1978 年,Dennis Ritchie 和 Brian Kernighan 合作推出了<The C Programming Language>的第一版(著作简称为 K ...

  8. VC运行时库(/MD、/MT等)

    VC项目属性→配置属性→C/C++→代码生成→运行时库 可以采用的方式有:多线程(/MT).多线程调试(/MTd).多线程DLL(/MD).多线程调试DLL(/MDd).单线程(/ML).单线程调试( ...

  9. C运行时库和标准C++库

    先理解运行时库,就是 C run-time library,是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数.VC提供的 C run-time libra ...

最新文章

  1. c语言求n(n从1到10),关于C语言的一道题
  2. IDEA 的 LeetCode 刷题插件 leetcode editor
  3. hdu 5036 Explosion bitset优化floyd
  4. 添加几个手机联系人_One UI 3.0: 更细腻、更好用,这才是手机系统该有的样子
  5. c 给定字符串中查找_面试 | 查找类算法精析
  6. 微软引入linux内核,微软内部已在讨论Linux内核中加入exFAT的可能性
  7. Android Studio中使用Git进行代码管理(分支、合并)
  8. 百度地图利用位置提供服务器,利用百度地图API获取当前位置信息的实例
  9. 今天日期减去过去日期_汽车各零部件也有身份证,教你们如何看这些部件的quot;出生日期quot;...
  10. sql server 2000能否得到一个表的最后更新日期?
  11. 论文赏析[ACL18]基于Self-Attentive的成分句法分析
  12. 词性标注-隐马尔可夫模型
  13. 违反计算机信息网络国际联网安全,给你普及一下为了加强对计算机信息网络国际联网的安全保护,维护公共秩序和社会稳定,早在1997年12月30日【刁爱青吧】_百度贴吧...
  14. GBDT(MART) 迭代决策树入门教程 | 简介 写的非常好!!
  15. 在腾讯云 EMR 上使用 GooseFS 加速大数据计算服务
  16. 高级查询(mysql)
  17. 百度大脑驾驶证识别使用攻略
  18. C#实践——计算GPA
  19. ArrayList类的详解
  20. 【Word】如何折叠Word文档中的段落

热门文章

  1. 劳动经济学-试题及答案汇总
  2. Hadoop源码解析
  3. STM32 HAL库开发学习笔记: USART1串口通讯(中断方式) IDE-STM32CubeIDE
  4. 支付集成(一):支付宝支付
  5. Android 超链接搜索
  6. unity学习之物理系统
  7. (初学者Java)火车站大屏幕火车信息显示系统
  8. PlantSimulation学习笔记:3种故障模式(Failure relates to)详解
  9. PHP 编写留言板
  10. 期刊论文的分析技巧与程序