900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Vc实战(2) 彻底厘清C运行库的涵义

Vc实战(2) 彻底厘清C运行库的涵义

时间:2023-07-03 12:34:25

相关推荐

Vc实战(2) 彻底厘清C运行库的涵义

一、什么叫C运行库:

1、由来:

C运行库,即C Runtime library,简称CRT。

C语言是小内核语言,其本身只处理少量的关键字、数据类型和基本流程控制。其内核开发出来后,C语言重写了Unix的90%的系统函数,并提取最常用的部分,形成了头文件和Lib库,C运行库产生。换言之,此时使用C语言本身和C运行库,在Unix下开发。

运行库包括C程序运行的最基本的函数,规模几近数千个函数。比如通过main开始运行,exit退出,printf之类的函数、错误处理等。换言之,没有运行库std,C程序根本不能运行。

2、Ansi C标准和 Standard Library

C逐渐流行,不同的编译厂商,在不同的平台上实现了Standard Library,当然都是平台相关的,这对于程序员而言显然带来紊乱。于是有了Ansi C标准,该标准除了详细定义C语言各要素的具体含义外, 同时规定了Standard Library的标准。因此Std由各编译厂商根据Ansi标准提供。

3、C++的标准库:

C++的Standard C++ Library,包括上面的C 运行库和Stl,显然,由于C++是C的超级,C运行库被简单的加入,没有必要另写一套。

二、VC++里的C运行库

在vs中,同一解决方案,每个项目应使用相同的C运行库。我们在解决方案资源管理器中,选中项目|右键|属性,打开该项目的属性页:配置属性|C/C++|代码生成,可以选择"运行库",有四个选择:多线程(/MT),多线程调试(/MTD),多线程Dll(/MD),多线程Dll调试(/MDD)。这四个选择,MT和MD是release版本,MTD和MDD是Debug版本,所以我们只要弄清MT和MD的区别。 /MT 即multithread, static version,多线程静态版本。这种方式下,编译器静态的链接LIBCMT.lib。/MD是multithread- and DLL-specific version,多线程DLL版本。这种方式下,编译器链接MSVCRT.lib,而动态的使用MSVCRT*.dll。它们的区别是:

1、静态运行时,使用LIBCMT.lib。动态运行时使用MSVCRT.lib+MSVCRT*.dll。

2、使用静态运行库,CRT会链接进EXE文件,生成的EXE文件大些,但运行时不用加载CRT。使用动态运行库,编译的EXE文件小些,但程序启动后需要Load CRT,加载MSVCRT*.dll文件,性能略低。

三、VC中C运行库设定的铁律:

1、同一解决方案,各项目使用相同的运行库设置,否则不仅可能无法生成,即使通过编译,也会带来多种潜在隐患

2、使用第三方库,必须编译和项目设置相同的版本,如果不能,则只能弃用。3、如果使用动态运行时/MD或/MDD,则MFC应用程序,只能选择在共享Dll中使用MFC,不能静态链接MFC。反过来说,如果MFC要静态链接到Exe文件,则必须使用/MT或/MTD

四、常见的编译错误:

当解决方案不同项目的运行库设置不同的时候,首先会出现一堆类似如下的错误:

MSVCRTD.lib(MSVCR120D.dll) : error LNK: _memmove 已经在 libcmtd.lib(memmove.obj) 中定义

然后:

LINK : warning LNK4098: 默认库“MSVCRTD”与其他库的使用冲突;请使用 /NODEFAULTLIB:library

fatal error LNK1169: 找到一个或多个多重定义的符号

原因很简单,Mfc应用和Dll项目之间,在链接另一个项目的类似lib、obj时,很明显,由于运行库设置不同,编译器面对两个运行库,选择链接哪一个运行库的函数,显然是很困难的事情,只好简单的告诉你:编译失败。将两者的运行库设置改为一致...无论哪一个,一致就好,问题解决。一些文章提到的另外两种解决方式:1、人为的忽略一个库;2、强制编译,都是有隐患的,某种意义上来说,是误导。请遵循上面提到的铁律:同一解决方案中,所有项目使用相同的运行库设置。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。