Trouble linking project ( repost )

I asked this yesterday:

I have taken on a job of moving a VC6 project to VC2005.  This product is so old, it uses XercesC because it predates MSXML ( so they tell me ), and it uses a number of other libraries as well.  One in particular ( a DICOM library ) gives me linker errors as follows:

"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 dcmimage.lib(diyp2img.obj)
msvcprtd.lib(MSVCP80D.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 dcmdata.lib(dcitem.obj)
msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,struct std::char_traits<char> >::operator<<(int)" ( 6 $basic_ostream@DU $char_traits@D@std@@@std@@QAEAAV01@H@Z) already defined in dcmimage.lib(diyp2img.obj)
msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: void __thiscall std::basic_ios<char,struct std::char_traits<char> >::setstate(int,bool)" ( setstate@ $basic_ios@DU $char_traits@D@std@@@std@@QAEXH_N@Z) already defined in dcmimage.lib(diyp2img.obj)
msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: int __thiscall std::ios_base::width(int)" ( width@ios_base@std@@QAEHH@Z) already defined in dcmimage.lib(diyp2img.obj)
msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: int __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::sputn(char const *,int)" ( sputn@ $basic_streambuf@DU $char_traits@D@std@@@std@@QAEHPBDH@Z) already defined in dcmimage.lib(diyp2img.obj)
msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: static bool __cdecl std::char_traits<char>::eq_int_type(int const &,int const &)" ( eq_int_type@ $char_traits@D@std@@SA_NABH0@Z) already defined in dcmimage.lib(diyp2img.obj)


etc.

Now, one thing I did with this project was move all the code to use standard headers, and I believe that iostream.h, etc, are not even present in VC2005 ( Microsoft rocks for their work on standards in c++ ).  I've actually built the library in VC2005, and made sure the project and the library use /MD to compile.  I tried moving to /MT, and that worked, excepting that it gave me an error from deep in MFC, so I've abandoned that, simply because it used to build using /MD, and I'm sure that's what the other libraries would be using. 

I have, in addition, created a new MFC project and tried to use this library, and got the same errors.  I'm wondering if it could be an issue with the improvements in the compiler, perhaps something is wrong in this library which VC6 just ignored

and got this reply:

Christian: I don't see anything here that indicates that the compiler is at fault: it looks to me as if the library dcimage.lib has, maybe, statically linked to libcpmt.lib

The weird thing is that some of these functions seem like they should be defined in a header file and thus should be marked as inline and thus the linker shouldn't complain.

Which tells me a lot more than I've been able to find out for the last week of trying.  My response was this:

Thanks for the reply - dcmimage.lib is building with /MD, and it's project properties include a 'librarian' group instead of 'linking' - I can't see anywhere that it sets that it statically links to anything.

Thanks for your help with this.

and got no reply :(  So, I'm still stuck.  How do I tell if the project is statically linking to libcpmt.lib What can I do about it

Thanks to all for looking.



Answer this question

Trouble linking project ( repost )

  • gmctech

    This was resolved off-line: one part of the project was defining its own std::string class and the errors were because some of the inline functions of this string class did not have exactly the same definition as the matching functions in the "real" std::string class that ships as part of Visual C++: hence the linker, correctly, was reporting multiple definitions errors for these functions.

  • Seyfert

    Sorry Christian: I didn't understand you were asking for more clarification.

    I would try linking with /verbose - that way at least you'll get more information about the order of the link process, and maybe a better understanding as to why the function is being brought in.

    You say that this library is built with /MD - it is dynamically bound to the C++ library - but if that was the case then I would expect to see a __imp__ prepended to the names of the functions above.

    I must admit I'm sort of clutching at straws here: if the application was statically linked then the functions in question (like eq_int_type) are inline functions and therefore they should be marked as COMDAT: which means that the linker can pick any definition. You might want to run link /dump /symbols over some of the object files and check that the functions are marked as COMDAT:

    0AF 00000000 SECT38 notype       Static       | .text
        Section length   14, #relocs    0, #linenums    0, checksum 6C7CF0BD, selection    2 (pick any)
    0B1 00000000 SECT38 notype ()    External     |
    eq_int_type@ $char_traits@D@std@@SA_NABH0@Z (public: static bool __cdecl std::char_traits<char>::eq_int_type(int const &,int const &))

    The "pick any" means it is a COMDAT function





  • Ido F.

    OK - here is the verbose linking ( just the error portion, the whole lot was *huge* )

    Searching D:\Program Files\Microsoft Visual Studio 8\VC\lib\msvcprtd.lib:

    Found __imp_ 1 $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAE@XZ

    Referenced in UltraCaptureSDIView.obj

    Referenced in Avimark.obj

    Referenced in Consult.obj

    Referenced in ExistingPatientDlg.obj

    Referenced in NewPatientDlg.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.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 dcmimage.lib(diyp2img.obj)

    Found __imp_ c_str@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBEPBDXZ

    Referenced in Avimark.obj

    Referenced in ExistingPatientDlg.obj

    Referenced in NewPatientDlg.obj

    Referenced in UltraCaptureSDIView.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: char const * __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::c_str(void)const " ( c_str@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBEPBDXZ) already defined in dcmimage.lib(diyp2img.obj)

    Found __imp_ A $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEAADI@Z

    Referenced in Avimark.obj

    Referenced in ExistingPatientDlg.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: char & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator[](unsigned int)" ( A $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEAADI@Z) already defined in dcmimage.lib(diyp2img.obj)

    Found __imp_ length@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBEIXZ

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ 0 $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAE@ABV01@@Z

    Referenced in Avimark.obj

    Referenced in ExistingPatientDlg.obj

    Referenced in NewPatientDlg.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.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 dcmimage.lib(diyp2img.obj)

    Found __imp_ 4 $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEAAV01@ABV01@@Z

    Referenced in Avimark.obj

    Referenced in NewPatientDlg.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ size@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBEIXZ

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: unsigned int __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::size(void)const " ( size@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBEIXZ) already defined in dcmimage.lib(diyp2img.obj)

    Found __imp_ 0 $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAE@PBD@Z

    Referenced in Avimark.obj

    Referenced in Consult.obj

    Referenced in ExistingPatientDlg.obj

    Referenced in NewPatientDlg.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.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 dcmimage.lib(diyp2img.obj)

    Found __imp_ 4 $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEAAV01@PBD@Z

    Referenced in Avimark.obj

    Referenced in NewPatientDlg.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ 0 $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z

    Referenced in Avimark.obj

    Referenced in ExistingPatientDlg.obj

    Referenced in NewPatientDlg.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ $ 8DU $char_traits@D@std@@V $allocator@D@1@@std@@YA_NABV $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@0@0@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ find_first_of@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBEIABV12@I@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ $ 9DU $char_traits@D@std@@V $allocator@D@1@@std@@YA_NABV $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@0@0@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ find_first_not_of@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBEIPBDI@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ substr@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBE AV12@II@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ find_last_not_of@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBEIPBDI@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ npos@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@2IB

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ _D $basic_ostringstream@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEXXZ

    Referenced in Avimark.obj

    Referenced in UltraCaptureSDIView.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.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 dcmdata.lib(dcitem.obj)

    Found __imp_ 6 $basic_ostream@DU $char_traits@D@std@@@std@@QAEAAV01@H@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,struct std::char_traits<char> >::operator<<(int)" ( 6 $basic_ostream@DU $char_traits@D@std@@@std@@QAEAAV01@H@Z) already defined in dcmimage.lib(diyp2img.obj)

    Found __imp_ str@ $basic_ostringstream@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEXABV $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@2@@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ 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

    Referenced in Avimark.obj

    Referenced in UltraCaptureSDIView.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.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 dcmdata.lib(dcitem.obj)

    Found __imp_ 6 $basic_ostream@DU $char_traits@D@std@@@std@@QAEAAV01@N@Z

    Referenced in Avimark.obj

    Referenced in UltraCaptureSDIView.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.dll) : error LNK2005: "public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,struct std::char_traits<char> >::operator<<(double)" ( 6 $basic_ostream@DU $char_traits@D@std@@@std@@QAEAAV01@N@Z) already defined in dcmimgle.lib(dimomod.obj)

    Found __imp_ 0 $basic_ostringstream@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAE@H@Z

    Referenced in Avimark.obj

    Referenced in UltraCaptureSDIView.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.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 dcmdata.lib(dcitem.obj)

    Found __imp_ Y $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEAAV01@PBD@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ 0 $basic_ostringstream@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAE@ABV $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@1@H@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ $ HDU $char_traits@D@std@@V $allocator@D@1@@std@@YA AV $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@0@ABV10@PBD@Z

    Referenced in Avimark.obj

    Referenced in ExistingPatientDlg.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ $ HDU $char_traits@D@std@@V $allocator@D@1@@std@@YA AV $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@0@ABV10@0@Z

    Referenced in Avimark.obj

    Referenced in ExistingPatientDlg.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ Y $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEAAV01@D@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    msvcprtd.lib(MSVCP80D.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> >::operator+=(char)" ( Y $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEAAV01@D@Z) already defined in dcmimgle.lib(didispfn.obj)

    Found __imp_ $ HDU $char_traits@D@std@@V $allocator@D@1@@std@@YA AV $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@0@ABV10@D@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Found __imp_ find_last_of@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QBEIDI@Z

    Referenced in Avimark.obj

    Loaded msvcprtd.lib(MSVCP80D.dll)

    Thanks again for any light you can shed on this.



  • draxx

    This function seams to be inline functions in a "normal" environment.
    Is it possible that you used some define to remove the inline keyword in a very early header

    It's just a try.


  • Aknght

    > Sorry Christian: I didn't understand you were asking for more clarification.

    That's cool, I appreciate any help you find the time to give.

    > I would try linking with /verbose - that way at least you'll get more information about the order of the link process, and maybe a better understanding as to why the function is being brought in.

    Did that, but I have to admit I didn't understand the result.  The project can't build right now ( updating from Paintlib to GDI+ ), but when it does, I could post the result.

    >You say that this library is built with /MD - it is dynamically bound to the C++ library - but if that was the case then I would expect to see a __imp__ prepended to the names of the functions above.

    As I said, when I build this project, I get a librarian group of options in the project instead of linking, but it is *definately* using /MDd ( I have looked at it so many times, I could tell you how many pixels it uses to do so ).

    What does the librarian group of options mean

    > check that the functions are marked as COMDAT:

    I will do that also when I get back to being able to do a build.

    Thanks again.


  • Aquind

    There is in fact a #define for inline, but funny enough, it's never used in the code ( and it sets it's value to be __inline, in any case ).



  • Bad_Bob

    Sounds possible, this is a cross platform library, compiled via CMake, and has a cross platform header thing that is quite complex and could be screwy somewhere.  I'll go and check.

    Thanks for the suggestion

  • Trouble linking project ( repost )