对于一个静态链接库L.lib,它的使用者app.exe会静态链接L.lib,意思是app.exe会将L.lib中的代码(app需要的部分,例如函数定义,类的定义等等)链接到app.exe中.
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的错误了,问题的根源已经找到,解决办法自己应该能想到了吧.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2015-05-27 socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题