链接错误:msvcprtd.lib(MSVCP90D.dll) : error LNK2005

1. 现象:

        在MFC项目中使用 boost 库的时候,出现了很多链接错误(如下)。其中 MFC项目 的配置是:

        错误:

                ①:msvcprtd.lib(MSVCP90D.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) 已经在 async_server.obj 中定义

                ②:MSVCRTD.lib(MSVCR90D.dll) : error LNK2005: __CrtDbgReportW 已经在 libcmtd.lib(dbgrptw.obj) 中定义

        等等,大概有接近200个类似错误。

2. 分析

        我们在编译C程序时,通常要链接 CRT(c run-time library)。CRT可分为动态库和静态库,动态库有两个:LIBCMTD.lib(debug版)和LIBCMT.lib(release版);静态库有两个:MSVCRTD.lib(debug)和MSVCRT.lib(release)。

        而MSVC项目对应为:

                多执行线程调试(/MTD):LIBCMTD.lib

                多执行线程(/MT):LIBCMT.lib

                多执行线程调试DLL(/MDd):MSVCRTD.lib

                多执行线程DLL(/MD):MSVCRT.lib

请注意,以上只是单纯 C 语言的程序库而没有包含 C++ 语言在内。如果你的程序系统中,有包含 C++ 语言的程序代码的话,那又是另外一回事了。但是在项目属性的页面中,为什么找不到相关的设定选项呢?因为 MSVC 悄悄地帮程序设计者代劳处理掉了。只要在程序代码中使用 #include 语法纳入任何一个 C++ 的标头文件,例如 iostream 或 fstream,MSVC 就会在链接器的运作阶段中,自动帮我们链接 C++ 的执行阶段程序库。而 C++ 的执行阶段程序库,同样可分为四个版本:

        静态链接:LIBCPMTD.lib(Debug版本)LIBCPMT.lib

        动态链接:MSVCPRTD.lib(Debug版本):执行文件相依于 MSVCP90D.dll
                            MSVCPRT.lib:执行文件相依于 MSVCP90.dll

        至于程序执行文件使用的是静态链接或者动态链接的版本,就仰赖于 C 语言的版本设定选项了。举个例子来说,如果你撰写了一个 Debug 组态的 C++ 程序,并且保留项目原先预设的生成选项(动态链接),那么最终生成出来的程序执行文件将会相依于 MSVCR90D.dll 以及 MSVCP90D.dll 两个 DLL 文件。如果将相同的程序以 Release 组态生成完成,则会相依于MSVCR90.dll 以及 MSVCP90.dll 二者。

        出现这些是因为程序同时链接了 LIBCMTD.lib与MSVCRTD.lib而造成函数定义版本冲突。也就是说,程序链接器已经在其中一个 CRT的版本中找到所需的函数定义,但此时却又跳出另外一位 CRT,也给了一份相同函数的实现版本,所以链接器无法判断应该忽略谁并且选择谁。而这个状况的发生原因,就是你的程序与程序所链接的外部程序库,使用了不同的 CRT版本之故。当时我在编译 boost 库的时候选择的选项中有 “link=static runtime-link=shared” ,所以生成的 lib 文件使用的是动态的 CRT ,而在上面的图中可以看到我的 MFC 项目中使用的是静态的CRT。所以出现冲突。

3. 解决办法

        方法一:重新编译 boost 库,采用 runtime-link=static 来编译。也就是说,你使用的第三方库必须编译时使用的是静态运行时库。

        方法二:将上面的 “MFC的使用” 选项改为“在共享 DLL 中使用 MFC”。(不推荐,可能还有其他库错误)

注:如果我们想写一个dll库,选择“多执行线程调试DLL(/MDd)”,那么我们应该使用 runtime-link=shared  编译的静态boost库。

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值