LNK2005 Error: basic_string already defined
-
Hello I am attempting to build a console application that depends on 4 other libraries using Visual Studio 2008. I was able to build the application in a previous version of Visual Studio. 3 of the libraries are in C code and the other is in C++. I have checked (more than once) that all the libraries and my application are all compiled using the multi-threaded DLL (/MD). My command line compile options for each library and my application are as follows: Lib1: /Ox /Op /MD Lib2&3: /Od /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_VC80_UPGRADE=0x0710" /D "_MBCS" /FD /EHsc /MD /W3 /c /Tc Lib4: /MD /EHsc /RTC1 /D "WIN32" /D "_MBCS" /W2 /DNDEBUG App: /Od /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_VC80_UPGRADE=0x0710" /D "_MBCS" /FD /EHsc /MD /W3 /c /TP Link: /INCREMENTAL /MANIFEST:NO /NODEFAULTLIB:"libcpmt.lib" /NODEFAULTLIB:"libc.lib" /NODEFAULTLIB:"libcmt.lib" I get 25 LNK2005 errors regarding basic_string already being defined in my application. I suspect it has something to do with lib4 because when I take it out of the project the LNK2005 errors go away and I get unresolved external errors for the functions I use out of that library (although I'm not sure what order those errors are generated in). I have tried ignoring msvcprt.lib but I get unresolved externals for other functions. :( I have turned on verbose to see what libraries are being included and they are as follows: lib4 lib2 lib3 lib1 zlib1.lib szlibdll.lib OLDNAMES.lib MSVCRT.lib msvcprt.lib (where the errors are given) uuid.lib kernel32.lib
Wow - you've already done a lot more investigation than most people who ask questions here :-) What can I suggest.... 1. I notice that some of your libs use "/Od" and others don't and others use "/Ox". This will affect how methods of template classes (like std::basic_string) are inlined in your libraries - it's possible (I think) that a std::basic_string method may be embedded in an object file and then re-exported from a library? 2. I'd be tempted to use
dumpbin
(it comes with VS) or objdump (comes with GCC, if you have that installed) to dump various properties of the lib files (usedumpbin /all _library-name_
) and then search through the resultant text for names ofbasic_string
methods that look like they're defined rather than referenced? 3. Or maybe delete lib4, then add object files back into lib4 one by one, to see when the LNK2005 occurs? So - no concrete answers, just possibilities :-(Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
Wow - you've already done a lot more investigation than most people who ask questions here :-) What can I suggest.... 1. I notice that some of your libs use "/Od" and others don't and others use "/Ox". This will affect how methods of template classes (like std::basic_string) are inlined in your libraries - it's possible (I think) that a std::basic_string method may be embedded in an object file and then re-exported from a library? 2. I'd be tempted to use
dumpbin
(it comes with VS) or objdump (comes with GCC, if you have that installed) to dump various properties of the lib files (usedumpbin /all _library-name_
) and then search through the resultant text for names ofbasic_string
methods that look like they're defined rather than referenced? 3. Or maybe delete lib4, then add object files back into lib4 one by one, to see when the LNK2005 occurs? So - no concrete answers, just possibilities :-(Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Thank you for your comprehensive reply:-) Suggestion 1 didn't work, but it is probably better to have them all the same anyway, considering what affect that option has. I used dumpbin on the offending library. It looks to me like it is defined but I would just like to check. In the exports table the functions (e.g. resize) that the linker complains about are external and prefixed with __imp_. Is this why the linker is complaining? Basically, one of the files in lib4 creates its own class which inherits from std::string. For older versions of C++, it has the lines #using std::string #define std_string string in the header file. For newer versions of Visual C++, it simply has #define std_string std::string What is the difference between these two? As far as I can see, the header file calls the functions in inline functions without the specifier std:: Other than that those functions aren't overridden or referred to anywhere else.
-
Thank you for your comprehensive reply:-) Suggestion 1 didn't work, but it is probably better to have them all the same anyway, considering what affect that option has. I used dumpbin on the offending library. It looks to me like it is defined but I would just like to check. In the exports table the functions (e.g. resize) that the linker complains about are external and prefixed with __imp_. Is this why the linker is complaining? Basically, one of the files in lib4 creates its own class which inherits from std::string. For older versions of C++, it has the lines #using std::string #define std_string string in the header file. For newer versions of Visual C++, it simply has #define std_string std::string What is the difference between these two? As far as I can see, the header file calls the functions in inline functions without the specifier std:: Other than that those functions aren't overridden or referred to anywhere else.
WendyS56 wrote:
In the exports table the functions (e.g. resize) that the linker complains about are external and prefixed with __imp_. Is this why the linker is complaining?
No - that's correct linkage to a function defined in a DLL.
WendyS56 wrote:
What is the difference between these two?
The first replaces
std_string
bystring
and relies on the using (not #using, I believe) statement to make string resolve to std::string. The second just replacesstd_string
bystd::string
. BTW - can you post the exact text of the LNK2005 message?Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
WendyS56 wrote:
In the exports table the functions (e.g. resize) that the linker complains about are external and prefixed with __imp_. Is this why the linker is complaining?
No - that's correct linkage to a function defined in a DLL.
WendyS56 wrote:
What is the difference between these two?
The first replaces
std_string
bystring
and relies on the using (not #using, I believe) statement to make string resolve to std::string. The second just replacesstd_string
bystd::string
. BTW - can you post the exact text of the LNK2005 message?Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Here are a few of the linker errors (ciwsgif is my application): msvcprt.lib(MSVCP90.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct>,class std::allocator >::basic_string<char,struct>,class std::allocator >(void)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in ciwsgif.obj msvcprt.lib(MSVCP90.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct>,class std::allocator >::basic_string<char,struct>,class std::allocator >(class std::basic_string<char,struct>,class std::allocator > const &)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z) already defined in ciwsgif.obj msvcprt.lib(MSVCP90.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct>,class std::allocator >::basic_string<char,struct>,class std::allocator >(char const *)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z) already defined in ciwsgif.obj
-
Here are a few of the linker errors (ciwsgif is my application): msvcprt.lib(MSVCP90.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct>,class std::allocator >::basic_string<char,struct>,class std::allocator >(void)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in ciwsgif.obj msvcprt.lib(MSVCP90.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct>,class std::allocator >::basic_string<char,struct>,class std::allocator >(class std::basic_string<char,struct>,class std::allocator > const &)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV01@@Z) already defined in ciwsgif.obj msvcprt.lib(MSVCP90.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct>,class std::allocator >::basic_string<char,struct>,class std::allocator >(char const *)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z) already defined in ciwsgif.obj
WendyS56 wrote:
already defined in ciwsgif.obj
I'm presuming
ciwsgif.cpp
is in one of your libraries?Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
WendyS56 wrote:
already defined in ciwsgif.obj
I'm presuming
ciwsgif.cpp
is in one of your libraries?Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Yes, ciwsgif is my main application file which uses the 4 libraries. It includes , and along with some header files corresponding to the 4 libraries.
-
Yes, ciwsgif is my main application file which uses the 4 libraries. It includes , and along with some header files corresponding to the 4 libraries.
Well...that's where the conflicting definitions are coming from
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
Well...that's where the conflicting definitions are coming from
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Do you mean if my application includes "string.h" and some other library header files include "string" or "CString" then there would be a conflict? Or is it because there are multiple includes of the same header file (i.e. string.h)?
-
Do you mean if my application includes "string.h" and some other library header files include "string" or "CString" then there would be a conflict? Or is it because there are multiple includes of the same header file (i.e. string.h)?
WendyS56 wrote:
Do you mean if my application includes "string.h" and some other library header files include "string" or "CString" then there would be a conflict? Or is it because there are multiple includes of the same header file (i.e. string.h)?
No - multiple includes shouldn't do that. What that message is saying is that your main object contains definitions for the string methods. I'm not sure why, but that's what the message is saying.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
WendyS56 wrote:
Do you mean if my application includes "string.h" and some other library header files include "string" or "CString" then there would be a conflict? Or is it because there are multiple includes of the same header file (i.e. string.h)?
No - multiple includes shouldn't do that. What that message is saying is that your main object contains definitions for the string methods. I'm not sure why, but that's what the message is saying.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
Thank you for clarifying things for me :) When running dumpbin and looking at all the EXPORTS, basic_string is EXPORT'ed from lib4. I understand that to mean that these functions are made available by that library. Am I correct? Would it make a difference to dynamically link my application to the libraries rather than statically linking to the .libs?
-
Thank you for clarifying things for me :) When running dumpbin and looking at all the EXPORTS, basic_string is EXPORT'ed from lib4. I understand that to mean that these functions are made available by that library. Am I correct? Would it make a difference to dynamically link my application to the libraries rather than statically linking to the .libs?
WendyS56 wrote:
Would it make a difference to dynamically link my application to the libraries rather than statically linking to the .libs?
Could well do - with DLLs, you explicitly specify what is exported, whereas with static libraries, there's less control over what is visible from the library.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
WendyS56 wrote:
Would it make a difference to dynamically link my application to the libraries rather than statically linking to the .libs?
Could well do - with DLLs, you explicitly specify what is exported, whereas with static libraries, there's less control over what is visible from the library.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
My program compiles and links successfully now :laugh: I used dynamic linking to lib4. I then needed to remove the NODEFAULTLIB:"libcpmt.lib and NODEFAULTLIB:"libc.lib" from my application link options. (I still needed to have NODEFAULTLIB:"libcmt.lib") Thank you for your help!
-
My program compiles and links successfully now :laugh: I used dynamic linking to lib4. I then needed to remove the NODEFAULTLIB:"libcpmt.lib and NODEFAULTLIB:"libc.lib" from my application link options. (I still needed to have NODEFAULTLIB:"libcmt.lib") Thank you for your help!
WendyS56 wrote:
My program compiles and links successfully now
Excellent! That wasn't so difficult now, was it :~ :-D
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p