VS链接器失败,显示“对象已存在".std :: string方法错误 [英] VS linker fails with "object already exists" error for std::string methods

查看:73
本文介绍了VS链接器失败,显示“对象已存在".std :: string方法错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我必须强调,我花了很长时间来解决它,而且我不知道自己缺少什么(或者更确切地说,是我不了解的东西).任何帮助将不胜感激!

First of all I must stress that I'm trying for quite some time to solve it, and I don't know what I am missing (or more precisely, what I don't understand). Any help will be greatly appreciated!

我有一个名为* static_tools *的项目,该项目可编译为名为 static_tools.lib 的静态库,并且使用STL.我用/MD编译了该项目,并且编译成功.

I have a project called *static_tools* that compiles to a static lib which is called static_tools.lib and it uses STL. I compile that project with /MD, and it compiles successfully.

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

Another project called system compiles to a DLL which is called system.dll also uses STL and links with static_tools.lib. I compile that project with /MD and it compiles successfully.

这是问题所在:另一个名为 systemclient 的(第三个)项目编译为一个名为 systemclient.dll 的DLL,该项目也使用STL和与 system.dll static_tools.lib 链接.我用/MD编译该项目,链接器失败:-(.

Here is the problem: Another (3rd) project called systemclient compiles to a DLL which is called systemclient.dll also uses STL and links with system.dll and static_tools.lib. I compile that project with /MD and the linker fails :-( .

错误是std :: string的方法已经存在于system.dll中.我认为是因为system.dll是从static_tools.lib中获取对象的,但是,如果这是真的,则听起来不可能使用静态lib,这是没有道理的.

The error is that methods of std::string already exists in system.dll. I think it happens because system.dll got the objects from static_tools.lib, but if it is true, it sounds like it is impossible to use static lib, which doesn't make sense.

更新-请求一些其他详细信息:

UPDATE - some extra details requested:

  • 我正在使用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,但是它不起作用:-(.

I have explicitly instantiate std::basic_string in stdafx.h, but it didn't work :-(.

有人可以在这里帮助我吗?另外,做个小小的解释也不错:-).

Can anyone help me out here? Also a small explanation would be nice :-).

推荐答案

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

Based on comments, your problem seems to be that you're explicitly instantiating std::string in the DLL and implicitly instantiating it in the staic library - these two instantiations will then cause a linker error.

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

The cleanest solution would be to not explicitly instantiate the template in the DLL. You mentioned you're doing it because your class is derived from std::string. It's generally a bad idea to (publically) derive from standard library containers, because they don't have a virtual destructor. So I'd look for ways to change your design accordingly, which would remove the need for explicit instantiation and the problem would disappear.

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

If that is not possible for one reason or another, you have a few other options. You mentioned VS2013, which should have support for the extern template feature of C++11. You could use that to provide an explicit instantiation declaration in the static library (so that it won't generate its own implicit instantiation) - it would then satisfy its link dependencies by the explicit instantiation in the DLL. Of course, that would mean all users of the static lib would have to supply the explicit instantation.

另一个选择是实际在静态库中显式实例化 std :: string ;然后DLL也将使用该显式实例化.

Another option would be to actually explicitly instantiate std::string in the static library; the DLL would then use that explicit instantiation as well.

编辑

我可以想到的另一个选择:创建一个新的DLL(例如 string.dll ),该DLL仅包含显式实例化的 std :: string .在其他两个DLL和静态库中使用 extern模板,并将 string.dll 链接到其他两个DLL.

One more option I can think of: create a new DLL (e.g. string.dll) which will only contain the explicitly instantiated std::string. Use extern template in the other two DLLs and the static lib, and link string.dll to the other two DLLs.

这篇关于VS链接器失败,显示“对象已存在".std :: string方法错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆