none
LNK2005 when using std::ostringstream RRS feed

  • Question

  • Hi all.

    Im using VS2010 under Windows 7 (64).

    Im building a large source package which is divided into two separate libraries (dynamic linking: .lib, .dll).

    in the first library, a.lib we are using both std::stringstream and std::ostringstream. a.lib depends on other libraries, all built by myself using CMake and VS2010. CMake defaults to /MD code generation (MultiThreaded). Im using this consistently over all my libraries (just double checked to be sure).

    When I build the next library, b.lib, which depends on a.lib, I get the following linking errors:

     

    Linking of b.lib:

    1>a.lib(agx.dll) : error LNK2005: "public: void __thiscall std::basic_ostringstream<char,struct std::char_traits<char>,class std::allocator<char> >::`vbase destructor'(void)" (??_D?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXXZ) already defined in ImageCapture.obj

    1>a.lib(agx.dll) : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall std::basic_ostringstream<char,struct std::char_traits<char>,class std::allocator<char> >::str(void)const " (?str@?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ) already defined in ImageCapture.obj

    1>a.lib(agx.dll) : error LNK2005: "public: __thiscall std::basic_ostringstream<char,struct std::char_traits<char>,class std::allocator<char> >::basic_ostringstream<char,struct std::char_traits<char>,class std::allocator<char> >(int)" (??0?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@H@Z) already defined in ImageCapture.obj

     

    Ok, I go into the sourcecode of ImageCapture.cpp and remove the use of std::ostringstream.

    And everything builds.

    Next, I try to use std::ostringstream in some other cpp file of the b.lib, so I just copy the code from ImageCapture.cpp into another .cpp file in b.lib, including the #include directives...

    It links just fine.

     

    One important thing to mention, all of this works just fine in VS2008.


    Next, I tried to change from std::ostringstream to std::stringstream in both a.lib AND b.lib.

     

    Now I get the same error, but instead its std::stringstream mentioned in the error message:

     

    2>a.lib(agx.dll) : error LNK2005: "public: void __thiscall std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> >::`vbase destructor'(void)" (??_D?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXXZ) already defined in ImageCapture.obj

    2>a.lib(agx.dll) : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> >::str(void)const " (?str@?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ) already defined in ImageCapture.obj

    2>a.lib(agx.dll) : error LNK2005: "public: __thiscall std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> >::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> >(int)" (??0?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@H@Z) already defined in ImageCapture.obj


    So, the situation is exactly the same, its just changed from std::ostringstream to std::stringstream.

    If I have just the right balance between stringstream and ostringstream, it builds. Then the problem occurs when I want to build a third library, depending on both a.lib AND b.lib...

    Then it starts all over.

    Anyone experienced this in VS2010?

     


    VR
    Wednesday, August 25, 2010 2:24 PM

All replies

  • Hi VRGURU,

    How did you reference a.lib in b.lib? As far as I know, the possible causes are showing below:
    1. Two project are built to different architectures. You need to check the platform target of the projects.
    2. A project reference one library as dynamic linking but another with static linking and the /clr is enabled. In other words, one library it reference is a dynamic library and the other is a static library. We need to make the references consistent.
    3. One library is of Debug version but the other is of Release version.

    You could take a look at the document below which shows more information about this error:
    http://msdn.microsoft.com/en-us/library/72zdcz6f.aspx

    Anyway, what I mention above is about the default compiler and linker in visual studio. Now that you use CMake as the builder, you need to connect to the author of it to get better support. As I know, CMake is a open source project and not one of the microsoft products.

    Let me know if this helps or not.
    Aland Li

    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
    Thursday, August 26, 2010 3:52 AM
    Moderator
  • Ok, I buy that, CMake might just do whatever, and you at MS does not have any responsibilities there.

    But to verify this I did the following:

    1. I have gone through each and every one of the depending libraries. They are all built with VS2010 and /MD (as I previously mentioned).

     

    1.5 They are all built in release mode.

    2. I used CMake (2.8.2) to generate VS2008 solution/project files.

    I built it with VS2008 (linking to the same dependencies built with VS2010 /MD).

    Guess what, it links just fine. It does not run though, but Im not surprised, it crashes in deque on some iterator code. That was just expected. VS2008 and VS2010 has completely different STL implementations. But they seem to be binary compatible anyway.

     

    3. Ok, next step, clean the build in VS2008, close VS2008, start a new command prompt for VS2010, open the solution file, waiting for the conversion to VS2010. No errors.

    Rebuild the solution. It fails on: 

     

     

    4>a.lib(agx.dll) : error LNK2005: "public: void __thiscall std::basic_ostringstream<char,struct std::char_traits<char>,class std::allocator<char> >::`vbase destructor'(void)" (??_D?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEXXZ) already defined in ImageCapture.obj

    4>a.lib(agx.dll) : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall std::basic_ostringstream<char,struct std::char_traits<char>,class std::allocator<char> >::str(void)const " (?str@?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@XZ) already defined in ImageCapture.obj

    4>a.lib(agx.dll) : error LNK2005: "public: __thiscall std::basic_ostringstream<char,struct std::char_traits<char>,class std::allocator<char> >::basic_ostringstream<char,struct std::char_traits<char>,class std::allocator<char> >(int)" (??0?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@H@Z) already defined in ImageCapture.obj


    So your guess is as good as mine. I think I have proved that CMake does not have anything to do with this. I'm completely stuck on this.


     


    VR
    • Edited by VRGURU Thursday, August 26, 2010 12:44 PM
    Thursday, August 26, 2010 12:23 PM
  • I have both VS2008 AND VS2010 installed on the computer, could that be a problem?

    That for some reason, VS2010 picks up some system libraries which are VS2008? But should really cause more problems all over the place...

     

    Newsflash: just tried to build on a different machine where ONLY VS2010 is installed. Same problem.

     

    /a


    VR
    Thursday, August 26, 2010 12:41 PM
  • Hi VRGURU,

    I tried to reproduce the issue but failed. Could you please create some small projects where the issue can be reproduced and upload it to sky driver for me to download?

    The thread below talks about a similar issue:
    http://social.msdn.microsoft.com/Forums/en/vclanguage/thread/91e576b9-b315-4e06-b189-e6b72af1af11

    Regards,
    Aland Li

    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
    Friday, August 27, 2010 7:32 AM
    Moderator
  • Found the reason. I had one class which was derived from std::ostringstream.
    I located this by 

     

    This has been working in VC6, VC2003, VC2005, VC2008, all gcc versions since 2.x somewhere around 2000.
    Up until now (VC2010). 

    It looks like that, when deriving from std::stringstream, I opened a can of worms.
    I looked into what symbols our library exported, and I found:

    const ns::Notify::`vftable'{for `std::basic_ostringstream<char,struct std::char_traits<char>,class std::allocator<char> >'}

    which is not really that strange, because the class Notify need to have a virtual table for the methods derived from ostringstream.
    But this seems to have caused the problem, because now its gone, and everything builds.

    So instead of:

    class EXPORT_API Notify : public std::ostringstream
    {

      ...

    };

     

    I use

     

    class EXPORT_API Notify
    {

      Notify& operator<<(...);

    etc...

    private:
      std::ostringstream m_stream;

    };

    I little bit more work, but at least it works. So the question is, why is it suddenly not possible to derive from std::ostringstream? I have not tried to reduce this to the smallest possible example, in our case, this was the one place where we had a class derived from ostringstream, and it spread the ostringstream symbols out of the library and into libraries depending on it.

    /A


    VR
    Friday, August 27, 2010 6:30 PM
  • So the question is, why is it suddenly not possible to derive from std::ostringstream? I have not tried to reduce this to the smallest possible example, in our case, this was the one place where we had a class derived from ostringstream, and it spread the ostringstream symbols out of the library and into libraries depending on it.

    I have seen a couple discussions that might be related to this on the release candidate forum:

    http://social.msdn.microsoft.com/Forums/en-US/vcpluslanguage/thread/a4596433-c651-48d4-adf8-3d0e341b073c

    http://social.msdn.microsoft.com/Forums/en-US/vcpluslanguage/thread/070e88e1-9c30-4068-aec9-902c81297f58

    http://social.msdn.microsoft.com/Forums/en-US/vcpluslanguage/thread/273c5fcc-a8d3-4b72-b1bd-22d576923f52

    http://social.msdn.microsoft.com/Forums/en-US/vcpluslanguage/thread/4238e162-21d2-46f6-a8f1-e1191cf1b200


     

    Friday, August 27, 2010 7:29 PM
  • mm, it all points in one direction. VC2010 is doing something else regarding the export of STL stuff.

    Which causes all kinds of problems. So I guess it can be considered to be a bug.

     

    /A


    VR
    Saturday, August 28, 2010 11:16 AM
  • Hi VRGURU,

    I create a class as you described but did not see the same issue.
    In a.lib:

    Notify.h:

    #pragma once
    
    #include <sstream>
    #include <string>
    
    class __declspec(dllexport) MyNotify : public std::ostringstream
    {
    public:
    	void ShowMsg(const std::string& str);
    };
    

     

    Notify.cpp:

    #include "stdafx.h"
    #include "Notify.h"
    
    void MyNotify::ShowMsg(const std::string& str)
    {
    	 (*this) << str << "fdfd";
    }
    

    In b.lib:
    Testing code:

    // b.cpp : Defines the exported functions for the DLL application.
    //
    
    #include "stdafx.h"
    #include <sstream>
    #include "../a/Notify.h"
    
    extern "C" void __declspec(dllimport) ShowMsg(string msg);
    
    extern "C" __declspec( dllexport ) void Display()
    {
    	MyNotify oss;
    	oss.ShowMsg("Hello");
    	ostringstream ss("ss");
    	ShowMsg("Hello");
    }
    
    

    It is suggested updating your visual studio 2010 so that all the latest patches are installed.

    On the other hand, the link provided by Fredrick_V below shows a similar issue:
    https://connect.microsoft.com/VisualStudio/feedback/details/562448/std-string-npos-lnk2001-when-inheriting-a-dll-class-from-std-string?wa=wsignin1.0

    Regards,
    Aland Li


    Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
    Monday, August 30, 2010 8:33 AM
    Moderator
  • Hi,

    I am writing to check the status of the issue on your side. Could you please let me know if the suggestion works for you? If you have any questions or concerns, please feel free to let me know. I will be more than happy to be of assistance.

     

    Regards,
    Aland Li

    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
    Wednesday, September 1, 2010 9:47 AM
    Moderator
  • Hi Aland,

    If you override the constructor/member functions already in std::ostringstream,  you'll most likely have the same problem.

    We had a class derived from std::basic_string<TCHAR>. It caused the same LNK2005 error. WE had to resort to the same technique that VRGURU had used.

    Regards,

    Jun

    Wednesday, September 1, 2010 10:34 PM
  • Hi Jun,

    Could you please provide a complete code snippet of the derived class?

    On the other hand, you could submit a feedback in the link below if the issue can be reproduced easily:
    https://connect.microsoft.com/VisualStudio
    Actually the feedback below shows the same issue, you can wait for visual studio team to fix it or someone to provide a workaround:
    https://connect.microsoft.com/VisualStudio/feedback/details/562448/std-string-npos-lnk2001-when-inheriting-a-dll-class-from-std-string?wa=wsignin1.0

    Regards,
    Aland Li

    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread.
    Thursday, September 2, 2010 1:05 PM
    Moderator
  • As an FYI, the ticket in your second link has been marked as "Closed, [behavior] by Design".  There seems to be some confusion on whether the dev team thinks this is a bug or not.  Also, under that link there is a workaround posted (replace uses of std::string::npos with size_t(-1)).
    Thursday, September 2, 2010 3:44 PM
  • Thanks guys, This help me fix the same issue by using containment replacing original inheritance from ostringstream class. I had almost given up and was inititaing to contact microsoft on this issue.

    Wednesday, November 23, 2011 1:37 PM