静态链接和动态链接库混用导致的链接错误LINK2005
2012-02-21 19:17
519 查看
对于一个静态链接库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的错误了,问题的根源已经找到,解决办法自己应该能想到了吧.
本文出自 “零一小筑” 博客,请务必保留此出处http://jetyi.blog.51cto.com/1460128/785974
而对于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的错误了,问题的根源已经找到,解决办法自己应该能想到了吧.
本文出自 “零一小筑” 博客,请务必保留此出处http://jetyi.blog.51cto.com/1460128/785974
相关文章推荐
- 静态链接和动态链接库混用导致的链接错误LINK2005
- 静态链接和动态链接库混用导致的链接错误LIN
- 静态链接和动态链接库混用导致的链接错误LINK2005
- 【转】动态链接库的静态链接导致程序的DLL劫持漏洞-借助QQ程序xGraphic32.dll描述
- 关于 加载第三方库的时候出现link2005 链接错误的解决办法
- json静态链接错误:msvcprtd.lib(MSVCP100D.dll) : error LNK2005:解决方案
- json静态链接错误:msvcprtd.lib(MSVCP100D.dll) : error LNK2005:解决方案
- 动态链接库的静态链接导致程序的DLL劫持漏洞-借助QQ程序xGraphic32.dll描述 .
- 动态链接库的静态链接导致程序的DLL劫持漏洞-借助QQ程序xGraphic32.dll描述
- 链接错误LNK2005 在MFC库之前链接C运行时库导致的链接错误
- VC缺省链接库的顺序不对导致链接错误error LNK2005: "void __cdecl operator delete(void *)"
- C和MFC链接错误Link2005
- VC缺省链接库的顺序不对导致链接错误error LNK2005: "void __cdecl operator delete(void *)"
- 错误:在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: SQL 网络接口, error: 26 - 定位指定的服务器/实例时出错) 解
- 模板函数(template function)出现编译链接错误(link error)之解析
- 解决mysql数据库因过多错误链接导致拒绝访问的问题
- 在 Visual C++ 中以错误的顺序链接 CRT 库和 MFC 库时出现 LNK2005 错误
- 解决VS2010链接错误:LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- 未包含链接库文件ws2_32.lib导致的错误
- VS2005链接问题: LNK2005错误 :error LNK2005: _free 已经在 libcmtd.lib(dbgheap.obj) 中定义