我目前有两个DLL库-CMN和GT。GT依赖于CMN。
在VisualStudio2003中,我可以毫无问题地编译和链接这两个库。我可以在Visual Studio 2010中成功编译CMN和GT,并链接CMN。然而,如果我试图链接GT,我会得到以下错误:
CMN.lib(CMN.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 TokenizerAdvanced.obj
CMN.lib(CMN.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 TokenizerAdvanced.obj
CMN.lib(CMN.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 TokenizerAdvanced.obj
CMN.lib(CMN.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 TokenizerAdvanced.obj
CMN.lib(CMN.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> >::erase(unsigned int,unsigned int)" (?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@II@Z) already defined in TokenizerAdvanced.obj
TokenizerAdvanced是GT.中的一个源文件
所有编译和链接都使用相同的命令行结构完成(使用-MDd进行编译)。Visual Studio 2003和2010之间发生了什么变化,会导致此问题?
编辑:奇怪的是,如果我从构建中排除TokenizerAdvanced.cpp(另一个文件-Tokenizer.cpp没有引用它),我会得到一个未解决的外部错误:
Tokenizer.obj : error LNK2001: unresolved external symbol "public: static unsigned int const std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::npos" (?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2IB)
编辑:将调查移至答案。
我想我已经找到问题了。我们有从CMN中的字符串派生的类。请参见此处。
此讨论建议在客户端库源代码中添加以下内容:
template std::string::size_type std::string::npos;
template std::wstring::size_type std::wstring::npos;
但这并没有解决我的问题。
这次讨论建议更改任何从字符串派生的类(我注意到我们的代码在一些地方这样做),改为使用包含,这就是我最终所做的。这解决了问题。