首先,我必须强调,我已经尝试了很长一段时间来解决它,而且我不知道我错过了什么(或者更准确地说,我不明白什么)。任何帮助将不胜感激!
我有一个名为 *static_tools* 的项目,它编译成一个名为 static_tools.lib 的静态库,它使用 STL。我用/MD 编译那个项目,它编译成功。
另一个名为 system 的项目编译成一个名为 system.dll 的 DLL,它也使用 STL 并与 static_tools.lib 链接。我使用/MD 编译该项目并成功编译。
问题在于:另一个(第 3 个)名为 systemclient 的项目编译成一个名为 systemclient.dll 的 DLL,它也使用 STL 和与 system.dll 和 static_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/