您的位置:首页 > 其它

VC下 Runtime 版本不同原因引起的一个编译问题案例

2013-03-01 14:23 393 查看

Background

MSDN中对于在不同的配置下Link的LIB作了说明:
C Runtime Library:
开关

对应的库

版本

/MD

MSVCRT.LIB

多线程DLL的Release版本

/MDd

MSVCRTD.LIB

多线程DLL的Debug版本

/MT

LIBCMT.LIB

多线程静态链接的Release版本

/MTd

LIBCMTD.LIB

多线程静态链接的Debug版本

/clr

MSVCMRT.LIB

托管代码和非托管代码混合

/clr:pure

MSVCURT.LIB

纯托管代码

C++ Standard Library:
开关

对应的库

版本

/MD

MSVCPRT.LIB

多线程DLL的Release版本

/MDd

MSVCPRTD.LIB

多线程DLL的Debug版本

/MT

LIBCPMT.LIB

多线程静态链接的Release版本

/MTd

LIBCPMTD.LIB

多线程静态链接的Debug版本

编译器会自动根据编译选项,选择对应的LIB文件。一般情况下这不会出现问题。
然而,在部分情况下,一旦你的程序的各个部分(LIB, OBJ…)并非由相同的编译选项编译出,而Link在一起的话,会出现各种各样的看似很难解决的问题,这类问题主要以重复定义的错误形式存在,通常的解决方法也很简单,就是选择同样的编译选项进行编译之后再Link。

Case Study

之前刚下载了ANTLR,在准备编译它的Example的时候发现了下面的Build错误(我自己为这个例子创建了VS的项目,当前配置为动态链接Runtime库,Debug版):
1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::replace(unsigned
int,unsigned int,char const *,unsigned int)" (?replace@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@IIPBDI@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: void __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::reserve(unsigned int)" (?reserve@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXI@Z)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: unsigned int __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::length(void)const " (?length@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator+=(class
std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??Y?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@ABV01@@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > const &)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: char const & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator[](unsigned int)const " (??A?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEABDI@Z)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator=(class
std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@ABV01@@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator=(char
const *)" (??4?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV01@PBD@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(char const *)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl std::operator+<char,struct std::char_traits<char>,class std::allocator<char> >(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??$?HDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@ABV10@0@Z)
already defined in antlr.lib(MismatchedCharException.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: char const * __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::c_str(void)const " (?c_str@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEPBDXZ)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "bool __cdecl std::operator<<char,struct std::char_traits<char>,class std::allocator<char> >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > const &)" (??$?MDU?$char_traits@D@std@@V?$allocator@D@1@@std@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,struct std::char_traits<char> >::operator<<(class std::basic_ostream<char,struct std::char_traits<char>
> & (__cdecl*)(class std::basic_ostream<char,struct std::char_traits<char> > &))" (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,struct std::char_traits<char> >::operator<<(int)" (??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::endl(class std::basic_ostream<char,struct std::char_traits<char> > &)" (?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: void __thiscall std::basic_ios<char,struct std::char_traits<char> >::setstate(int,bool)" (?setstate@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: int __thiscall std::ios_base::width(int)" (?width@ios_base@std@@QAEHH@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: int __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::sputn(char const *,int)" (?sputn@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHPBDH@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: static bool __cdecl std::char_traits<char>::eq_int_type(int const &,int const &)" (?eq_int_type@?$char_traits@D@std@@SA_NABH0@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: static int __cdecl std::char_traits<char>::eof(void)" (?eof@?$char_traits@D@std@@SAHXZ) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: int __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::sputc(char)" (?sputc@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEHD@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_streambuf<char,struct std::char_traits<char> > * __thiscall std::basic_ios<char,struct std::char_traits<char> >::rdbuf(void)const " (?rdbuf@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEPAV?$basic_streambuf@DU?$char_traits@D@std@@@2@XZ)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: char __thiscall std::basic_ios<char,struct std::char_traits<char> >::fill(void)const " (?fill@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEDXZ) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: int __thiscall std::ios_base::flags(void)const " (?flags@ios_base@std@@QBEHXZ) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: int __thiscall std::ios_base::width(void)const " (?width@ios_base@std@@QBEHXZ) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: static unsigned int __cdecl std::char_traits<char>::length(char const *)" (?length@?$char_traits@D@std@@SAIPBD@Z) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,struct std::char_traits<char> >::flush(void)" (?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_ostream<char,struct std::char_traits<char> > * __thiscall std::basic_ios<char,struct std::char_traits<char> >::tie(void)const " (?tie@?$basic_ios@DU?$char_traits@D@std@@@std@@QBEPAV?$basic_ostream@DU?$char_traits@D@std@@@2@XZ)
already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: bool __thiscall std::ios_base::good(void)const " (?good@ios_base@std@@QBE_NXZ) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: void __thiscall std::basic_ostream<char,struct std::char_traits<char> >::_Osfx(void)" (?_Osfx@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEXXZ) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: void __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::_Lock(void)" (?_Lock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: void __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::_Unlock(void)" (?_Unlock@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXXZ) already defined in antlr.lib(CharScanner.obj)

1>msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::operator<<<char,struct std::char_traits<char>,class std::allocator<char> >(class std::basic_ostream<char,struct std::char_traits<char>
> &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??$?6DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z)
already defined in antlr.lib(LLkParser.obj)

1>libcpmt.lib(locale0.obj) : error LNK2005: "private: static class std::locale::_Locimp * __cdecl std::locale::_Getgloballocale(void)" (?_Getgloballocale@locale@std@@CAPAV_Locimp@12@XZ) already defined in msvcprtd.lib(MSVCP80D.dll)

1>libcpmt.lib(locale0.obj) : error LNK2005: "private: static void __cdecl std::locale::facet::facet_Register(class std::locale::facet *)" (?facet_Register@facet@locale@std@@CAXPAV123@@Z) already defined in msvcprtd.lib(MSVCP80D.dll)

1>libcpmt.lib(locale0.obj) : error LNK2005: "public: static void __cdecl std::_Locinfo::_Locinfo_dtor(class std::_Locinfo *)" (?_Locinfo_dtor@_Locinfo@std@@SAXPAV12@@Z) already defined in msvcprtd.lib(MSVCP80D.dll)

1>libcpmt.lib(locale0.obj) : error LNK2005: "public: static void __cdecl std::_Locinfo::_Locinfo_ctor(class std::_Locinfo *,char const *)" (?_Locinfo_ctor@_Locinfo@std@@SAXPAV12@PBD@Z) already defined in msvcprtd.lib(MSVCP80D.dll)

1>libcpmt.lib(xmutex.obj) : error LNK2005: "public: void __thiscall std::_Mutex::_Lock(void)" (?_Lock@_Mutex@std@@QAEXXZ) already defined in msvcprtd.lib(MSVCP80D.dll)

1>libcpmt.lib(xmutex.obj) : error LNK2005: "public: void __thiscall std::_Mutex::_Unlock(void)" (?_Unlock@_Mutex@std@@QAEXXZ) already defined in msvcprtd.lib(MSVCP80D.dll)

1>libcpmt.lib(xlock.obj) : error LNK2005: "public: __thiscall std::_Lockit::_Lockit(int)" (??0_Lockit@std@@QAE@H@Z) already defined in msvcprtd.lib(MSVCP80D.dll)

1>libcpmt.lib(xlock.obj) : error LNK2005: "public: __thiscall std::_Lockit::~_Lockit(void)" (??1_Lockit@std@@QAE@XZ) already defined in msvcprtd.lib(MSVCP80D.dll)

1>LIBCMT.lib(invarg.obj) : error LNK2005: __invoke_watson already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(invarg.obj) : error LNK2005: __invalid_parameter already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(setlocal.obj) : error LNK2005: __configthreadlocale already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(tidtable.obj) : error LNK2005: __encode_pointer already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(tidtable.obj) : error LNK2005: __decode_pointer already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(tolower.obj) : error LNK2005: _tolower already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(crt0dat.obj) : error LNK2005: __amsg_exit already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(crt0dat.obj) : error LNK2005: __initterm_e already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(crt0dat.obj) : error LNK2005: _exit already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(crt0dat.obj) : error LNK2005: __exit already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(crt0dat.obj) : error LNK2005: __cexit already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(lconv.obj) : error LNK2005: _localeconv already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(mlock.obj) : error LNK2005: __unlock already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(mlock.obj) : error LNK2005: __lock already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(winxfltr.obj) : error LNK2005: __XcptFilter already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xi_a already defined in MSVCRTD.lib(cinitexe.obj)

1>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xi_z already defined in MSVCRTD.lib(cinitexe.obj)

1>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xc_a already defined in MSVCRTD.lib(cinitexe.obj)

1>LIBCMT.lib(crt0init.obj) : error LNK2005: ___xc_z already defined in MSVCRTD.lib(cinitexe.obj)

1>LIBCMT.lib(hooks.obj) : error LNK2005: "void __cdecl terminate(void)" (?terminate@@YAXXZ) already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(crt0.obj) : error LNK2005: _mainCRTStartup already defined in MSVCRTD.lib(crtexe.obj)

1>LIBCMT.lib(errmode.obj) : error LNK2005: ___set_app_type already defined in MSVCRTD.lib(MSVCR80D.dll)

1>LIBCMT.lib(_ctype.obj) : error LNK2005: _isprint already defined in MSVCRTD.lib(MSVCR80D.dll)

1>MSVCRTD.lib(MSVCR80D.dll) : error LNK2005: __stricmp already defined in LIBCMT.lib(stricmp.obj)

1>LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library

1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library

1>D:/home/doc/Visual Studio 2005/Projects/tst_antlr_3/Debug/tst_antlr_3.exe : fatal error LNK1169: one or more multiply defined symbols found

分析一下错误来源,会发现:
1. 错误来源主要是重复定义的问题,而且重复定义的基本上都是VC Runtime和Standard C++ Library中的函数
2. LIBCMT和LIBCPMT为Release下的Lib,本来不应该出现在Debug版本的链接的Lib中
3. 重复定义的问题主要出现在:LIBCMT, LIBCPMT, MSVCPRTD, MSVCRTD
来看看出问题的LIB是那些:
1. LIBCMT:C Runtime库的多线程静态链接的Release版本
2. LIBCPMT:C++ Standard Library的多线程静态链接的Release版本
3. MSVCPRTD:C++ Standard Library的多线程DLL的Debug版本
4. MSVCRTD:C Runtime Library的多线程DLL的Debug版本
当前我们的配置是多线程DLL的Debug版,因此3和4是应该出现在link的列表中的,不属于多余。而后两者则是只是当多线程静态链接Release版中才会出现。这提示我在项目中加入的ANTLR.LIB可能是造成这个问题的根源,因为静态库的编译选项很容易和主程序发生冲突,并且根据实际信息我们可以看出ANTLR.LIB应该是用多线程静态链接的Release版本来编译的。
这样,解决方法就很清楚了:
1. 切换到Release,因为ANTLR.LIB是在Release下面编译的
2. 把Run Time库的版本修改成多线程静态链接
做了这两个修改之后编译通过。
还有一种方法是,自己用多线程DLL的Debug版重新编译一次ANTLR,生成一个新的ANTLRD.LIB,再link这个Lib也可以解决这个问题。

Summary

1. 知道各个不同的LIB代表的版本信息非常重要,可以帮助快速定位问题
2. 在编程的时候,一定要把所有的项目的编译选项(是静态链接Runtime库还是动态链接Runtime库,Debug/Release)配置成一样的。如果部分LIB/OBJ是由第三方提供(OBJ情况很少见),一般情况下只能调整自己的编译选项,除非你可以要求第三方提供其他版本的编译好的LIB
3. 在发布可重用的静态LIB库供其他人调用的时候,最好对应不同的编译选项,乃至VC版本,提供不同版本的LIB。VC自己的Runtime就是最好的例子。
======================

This topic discusses the various .lib files that comprise the C run-time libraries as well as their associated compiler options and preprocessor directives.

The following libraries contain the C run-time library functions.

C run-time library (without iostream or standard C++ library)CharacteristicsOptionPreprocessor directives
LIBC.LIBSingle-threaded, static link/ML
LIBCMT.LIBMultithreaded, static link/MT_MT
MSVCRT.LIBMultithreaded, dynamic link (import library for MSVCR71.DLL). Be aware that if you use the Standard C++ Library, your program will need MSVCP71.DLL to run./MD_MT, _DLL
LIBCD.LIBSingle-threaded, static link (debug)/MLd_DEBUG
LIBCMTD.LIBMultithreaded, static link (debug)/MTd_DEBUG, _MT
MSVCRTD.LIBMultithreaded, dynamic link (import library for MSVCR71D.DLL) (debug)/MDd_DEBUG, _MT, _DLL
If you link your program from the command line without a compiler option that specifies a C run-time library, the linker will use LIBC.LIB.

To build a debug version of your application, the _DEBUG flag must be defined and the application must be linked with a debug version
of one of these libraries. For more information about using the debug versions of the library files, see CRT Debugging Techniques.

This version of Visual C++ is not conformant with the C99 standard.


Standard C++ Library

Note that starting in Visual Studio .NET 2003, Visual C++ will no longer ship the old iostream libraries. For details, see Upgrade to the Standard C++ Library and the Standard
C++ Library Overview.

The new iostream functions, as well as many other new functions, exist in the Standard C++ Library:

Standard C++ LibraryCharacteristicsOptionPreprocessor directives
LIBCP.LIBSingle-threaded, static link/ML
LIBCPMT.LIBMultithreaded, static link/MT_MT
MSVCPRT.LIBMultithreaded, dynamic link (import library for MSVCP71.dll)/MD_MT, _DLL
LIBCPD.LIBSingle-threaded, static link/MLd_DEBUG
LIBCPMTD.LIBMultithreaded, static link/MTd_DEBUG, _MT
MSVCPRTD.LIBMultithreaded, dynamic link (import library for MSVCP71D.DLL)/MDd_DEBUG, _MT, _DLL
When you build a release version of your project, one of the basic C run-time libraries (LIBC.LIB, LIBCMT.LIB, and MSVCRT.LIB) is linked by default, depending on the compiler option you choose (single-threaded, multithreaded, or DLL). If you include a Standard
C++ Library header in your code, a Standard C++ Library will be linked in automatically by Visual C++ at compile time. For example:

#include <ios>



What is the difference between msvcrt.dll and msvcr71.dll?

The msvcrt.dll is now a "known DLL," meaning that it is a system component owned and built by Windows. It is intended for future use only
by system-level components. An application should use and redistribute msvcr71.dll, and it should avoid placing a copy or using an existing copy of msvcr71.dll in the system directory. Instead, the application should keep a copy of msvcr71.dll in its application
directory with the program executable. Any application built with Visual C++ .NET using the /MD switch will necessarily use msvcr71.dll.


What problems exist if an application uses both msvcrt.dll and msvcr71.dll?

If you have a .lib or .obj file that needs to link to msvcrt.lib, then you should not have to recompile it to work with the new msvcrt.lib in Visual C++ .NET. The .lib or .obj file may rely on the sizes, field offsets, or member function names of various CRT
classes or variables, and those should all still exist in a compatible way. When you relink against msvcrt.lib, your final EXE and DLL image will now have a dependency on msvcr71.dll instead of msvcrt.dll.

If you have more than one DLL or EXE, then you may have more than one CRT, whether or not you are using different versions of Visual C++. For example, statically linking the CRT into multiple DLLs can present the same problem. Developers encountering this problem
with static CRTs have been instructed to compile with /MD to use the CRT DLL. Now that the CRT DLL has been renamed to msvcr71.dll, applications may have some components linked to msvcrt.dll and others to msvcr71.dll. If your DLLs pass CRT
resources across the msvcrt.dll and msvcr71.dll boundary, you will encounter issues with mismatched CRTs and need to recompile your project with Visual C++ .NET.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐