zoukankan      html  css  js  c++  java
  • 静态链接和动态链接库混用导致的链接错误LINK2005

    对于一个静态链接库L.lib,它的使用者app.exe会静态链接L.lib,意思是app.exe会将L.lib中的代码(app需要的部分,例如函数定义,类的定义等等)链接到app.exe中.

      而对于L.lib本身来说,它的CRT(C Run-Time Libraries)有多种配置,这里仅考虑/MTd.如果配置为/MTd,L.lib会链接静态库libcmtd.lib,这意味着会将libcmtd.lib中的代码(L.lib需要的部分,例如函数定义,类的定义等等)链接到L.lib中.为了更清楚说明问题,下面举一个例子.

    L.lib中有文件L.h和L.cpp,L.h的内容(部分)如下:
    #param once
    #include <string>
    void testfun();

    L.cpp中的内容(部分)如下:
    std::basic_string<char> g_teststring("aaaaaaaaaa");
    vod testfun(){
    //使用了标准静态库libcmtd.lib中的类,会将std::basic_string<char>定义代码复制到该模块中.
        std::basic_string<char> str(g_teststr);
    }

    Build之后生成L.lib,然后以二进制方式打开L.obj,可以看到如下内容:
    ...std::basic_string<char,std::char_traits<char>,std::allocator<char> >...
    很明显,L.obj包含有std::basic_string<char>的定义,这才是静态链接的含义.那么这会有什么问题呢?

      现在假设一种情况,E.exe的CRT配置为/MDd,这意味着它会动态链接msvcrtd.lib,同时E.exe也链接到L.lib,假如该工程中有一个文件E.CPP,它的内容如下:
    #include "L.h"
    #include <string>
    testfun();//来自于L.lib的头文件L.h
    std::string<char> g_teststdstring("bbbbbbbbbb"); //A

      Build该工程,就会发生LINK2005的错误:
    msvcprtd.lib(MSVCP90D.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 L.lib(L.obj)
      这个错误很明显指出,std::basic_string<char>重复定义,这是因为E.cpp在同时使用了L.lib和msvcrtd.lib,编译完成后,E.obj会链接L.lib和msvcrtd.lib时,此时发现在这两个库中都有std::basic_string<char>的定义,这显然是不允许的.

      如果将E.cpp中的A行代码改为:
    std::string<TCHAR> g_teststdstring(_T("bbbbbbbb"));
    就不会有链接错误LINK2005了.

      需要注意的是,如果E.cpp中出现关于vector的变量的定义,同样会出现LINK2005链接错误,即使你没有使用std::basic_string.这说明只要你在工程E.exe中同时使用了动态标准链接库和静态链接标准库,就有可能出现标准库中某些类型重复定义的错误.

    现在你应该彻底理解了LIN2005的错误了,问题的根源已经找到,解决办法自己应该能想到了吧.

  • 相关阅读:
    htmlcleaner使用及xpath语法初探
    薛兆丰 经济学思维:只给你讲地道的经济学思维 得到订阅专栏 下载
    解决web项目存在多个log4j.properties配置文件,导致日志级别配置不生效问题
    RC4被JDK8默认禁用导致腾讯QQ邮箱无法访问
    JavaMail SMTP服务器发送邮件程序示例 java通过dns服务器解析ip地址
    javamail-android
    使用POP3协议接收并解析电子邮件(全)
    [API]使用Blueprint来高雅的编写接口文档 前后端api文档,移动端api文档
    优酷真实视频地址解析——2016年9月20日 优酷视频下载工具
    记录思想分享知识编辑器 Markdown 编辑阅读器
  • 原文地址:https://www.cnblogs.com/lidabo/p/6913798.html
Copyright © 2011-2022 走看看