c++ - VS 链接器失败,std::string 方法出现 "object already exists"错误

标签 c++ visual-c++ stl build linker

首先,我必须强调,我已经尝试了很长一段时间来解决它,而且我不知道我错过了什么(或者更准确地说,我不明白什么)。任何帮助将不胜感激!

我有一个名为 *static_tools* 的项目,它编译成一个名为 static_tools.lib 的静态库,它使用 STL。我用/MD 编译那个项目,它编译成功。

另一个名为 system 的项目编译成一个名为 system.dll 的 DLL,它也使用 STL 并与 static_tools.lib 链接。我使用/MD 编译该项目并成功编译。

问题在于:另一个(第 3 个)名为 systemclient 的项目编译成一个名为 systemclient.dll 的 DLL,它也使用 STL 和与 system.dllstatic_tools.lib 的链接。我使用/MD 编译该项目,但链接器失败:-(。

错误是std::string的方法已经存在于system.dll中。 我认为这是因为system.dll从static_tools.lib中获取了对象,但如果是这样,听起来好像不可能使用静态库,这没有意义。

更新 - 需要一些额外的细节:

  • 我用的是VS2013,但是在VS2010也出现过
  • 我从链接器得到的错误:

2>static_tools.lib(pipe_client.obj) : error LNK2005: "public: __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >(wchar_t const *)" (??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@PEB_W@Z) already defined in system.lib(system.dll)

2>static_tools.lib(pipe_client.obj) : error LNK2005: "public: __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >::~basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >(void)" (??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ) already defined in system.lib(system.dll)

2>static_tools.lib(pipe_client.obj) : error LNK2005: "public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > & __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t>>::operator+=(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &)" (??Y?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV01@AEBV01@@Z) already defined in system.lib(system.dll)

2>static_tools.lib(pipe_client.obj) : error LNK2005: "public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > & __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t>>::append(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t>>const &)"(?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@AEBV12@@Z) already defined in system.lib(system.dll)

2>static_tools.lib(pipe_client.obj) : error LNK2005: "public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > & __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t>>::assign(wchar_t const *,unsigned __int64)" (?assign@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEAV12@PEB_W_K@Z) already defined in system.lib(system.dll)

2>static_tools.lib(pipe_client.obj) : error LNK2005: "public: wchar_t const * __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t>>::c_str(void)const " (?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ) already defined in system.lib(system.dll)

2>static_tools.lib(pipe_client.obj) : error LNK2005: "public: bool
__cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t>>::empty(void)const " (?empty@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_NXZ) already defined in system.lib(system.dll)

2>static_tools.lib(pipe_client.obj) : error LNK2005: "public: unsigned
__int64 __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t>>::size(void)const " (?size@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBA_KXZ) already defined in system.lib(system.dll)

2>static_tools.lib(error_tracer.obj) : error LNK2005: "public: __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >(void)" (??0?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ) already defined in system.lib(system.dll)

2>static_tools.lib(error_tracer.obj) : error LNK2005: "public: __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >::~basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >(void)" (??1?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAA@XZ) already defined in system.lib(system.dll)

2>static_tools.lib(error_tracer.obj) : error LNK2005: "public: wchar_t const * __cdecl std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t>>::c_str(void)const " (?c_str@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEBAPEB_WXZ) already defined in system.lib(system.dll)

我已经在 stdafx.h 中显式地实例化了 std::basic_string,但是它不起作用:-(。

有人可以帮我吗?还有一个小的解释会很好 :-)。

最佳答案

根据评论,您的问题似乎是您在 DLL 中显式实例化 std::string 并在 staic 库中隐式实例化它 - 这两个实例化将导致链接器错误.

最简洁的解决方案是不在 DLL 中显式实例化模板。您提到您这样做是因为您的类派生自 std::string。 (公开地)从标准库容器派生通常不是一个好主意,因为它们没有虚拟析构函数。因此,我会寻找相应的方法来更改您的设计,这样就不需要显式实例化,问题就会消失。

如果由于某种原因无法做到这一点,您还有其他一些选择。你提到了VS2013,它应该支持C++11的extern template特性。您可以使用它在静态库中提供显式实例化声明(这样它就不会生成自己的隐式实例化)——然后它将通过 DLL 中的显式实例化来满足其链接依赖性。当然,这意味着静态库的所有用户都必须提供显式实例化。

另一种选择是在静态库中显式实例化 std::string;然后 DLL 也会使用该显式实例化。

编辑

我能想到的另一个选择是:创建一个新的 DLL(例如 string.dll),它只包含显式实例化的 std::string。在另外两个DLL和静态库中使用extern template,将string.dll链接到另外两个DLL。

关于c++ - VS 链接器失败,std::string 方法出现 "object already exists"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21522320/

相关文章:

在 std::list 上使用删除时的 C++ 分段

.net - 如何构建 system::drawing::rectangle 的 vector

c++ - 使用 CDC 的 MFC 打印仅适用于某些打印机

C++11/14 将 std::uint32 转换为 std::vector<std::uint8>

c++ - c歧义中的字母数字到数字

C++ 应用程序在 64 位版本的 Windows 中崩溃,但在 32 位 Windows 上运行良好

visual-studio-2008 - 你能在加载的项目上制作一个 VC++ 解决方案集预处理器 #defines 吗?

visual-c++ - CDialog 和 CPropertySheet 验证最佳实践?

c++ - 如何在 C++ 中正确填写列表列表

c++ - remove_if 字符串匹配集合中的给定字符串