C++ – How to build a debug .exe (MSVCRTD.lib) against a release built lib (MSVCRT.lib)

c++linkervisual-c++visual-studio

I'm using Visual C++ 2008, SP1. I have a QT app (gui, .exe) in debug build config. It's set to use the Multi-threaded Debug DLL version of the CRT, aka MSVCRTD.lib.

I'm linking against a 3rd party library that is built in release mode and using the Multi-threaded DLL (non-debug) version of the CRT, aka MSVCRT.lib.

It links and runs but crashes at startup. While linking I get the warning:

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library

I tried setting /NODEFAULTLIB:msvcrt.lib

but that resulted in 5 linking errors due to missing symbols.

So is it not possible to use two different libs? What is the alternative? Can I create a DLL out of the 3rd party lib I have? Or is that something the 3rd party would have to do?

The exception at startup is:

"Unhandled exception at ……. in MyApp.exe: ……
Access violation reading location 0x00000000f"

The following is the call stack after the app is run and it crashes:

MyApp.exe!std::_Aux_cont::_Getcont()  + 0xa bytes   C++
MyApp.exe!std::_Iterator_base_aux::_Getmycont()  + 0x1b bytes   C++
MyApp.exe!std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,unsigned int,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,unsigned int> >,0> >::const_iterator::operator*()  + 0x28 bytes  C++
MyApp.exe!std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,unsigned int,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,unsigned int> >,0> >::iterator::operator*()  + 0xf bytes C++
MyApp.exe!std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,unsigned int,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,unsigned int> > >::operator[]()  + 0xe9 bytes    C++
MyApp.exe!ThirdPartyLib::client::`anonymous namespace'::init_xlt_mode()  + 0x5f bytes   C++
MyApp.exe!_GetCommandLineW@0()  + 0x8d8f3 bytes C++
msvcr90d.dll!_initterm(void (void)* * pfbegin=0x006c4468, void (void)* * pfend=0x006cb0b8)  Line 903    C
MyApp.exe!__tmainCRTStartup()  Line 501 + 0xf bytes C
MyApp.exe!WinMainCRTStartup()  Line 403 C
kernel32.dll!7c817067()     

Best Solution

You could build your project to link against the release CRT and enable debug information for your code. In "Project Properties" go to C++/General and change the Debug Information Format. In the "Optimization" section turn off optimization. Switch to the "Linker/Debugging" section and enable generation of debug info. Make sure to set the program database file (PDB).

At this point your application will emit debugging information for everything in your code and link against the non-debug DLL CRT. This enables you to debug your application in a Release configuration while avoiding the problems associated with using multiple CRTs in the same application.

Related Question