I've downloaded a 3rd party library, and built the .lib file in 'release' mode.
After adding the lib to my project, if i run my project in release mode, it's fine. But if i run my project in debug mode, i get an error:
_iterator_debug_level value '0' doesn't match value '2;
I could rebuild the library in debug mode, but I don't think I'll need to be debugging the library itself? And I've downloaded prebuilt 3rd party libraries before which only come with a release build (i assume?) that link fine whether my project is in debug or release. I'm wondering how that is done.
If you want to distribute a release library that others can use in either release or debug mode, you need to do two things:
Build a DLL, so that you get your own copy of the C runtime library
Not share CRT resources, such as the heap, across the library boundary. The biggest thing for C code is that dynamically allocated memory has to be deallocated on the same side of the boundary. For C++ code, you can use the std namespace inside your DLL, but not pass those objects across the boundary.
That's what the pre-built third-party libraries have most likely done. You can do the same thing with your library only if the external interface doesn't share CRT objects. Or you can build separate release and debug versions as static libraries.
Looks like your debug binary and the library you downloaded use incompatible iterator debug modes. Iterator debugging is usually controlled by macros. Depending on macro values the sizes of interators and many other objects can change. You are lucky that your program emitted useful error message instead of simply crushing.
Check the library documentation and make sure that your project uses the same iterator debug mode. You may also try recompiling the library in release mode. If that doesn't help, you would have to recompile the library in debug mode, even if you don't intend to debug the library itself.
Related
I was working on a MS Visual Studio project and noticed that the Debug build was Linking to a Release library (DLL), when a Debug library with the same name was also available. I switched the path to Link the Debug library, and it seems to still work. Is there any way to know if my change was correct?
Additional Information:
Using the debug DLL triggers a small memory leak that wasn't triggered with the release DLL. Or possibly that is debug related cache data. That leak made me question if it was including the lib headers without _DEBUG somehow. Thus this question.
It is the preferred way to link Debug builds of your program with Debug version of external dynamic libraries as it guarantees that uniform Visual C++ runtime libraries will be used. Mixing libraries built in Debug and Release mode will result in both Debug and Release VC++ runtimes being linked and annoying linker warnings about multiple symbol definitions in conflicting Debug/Runtime libraries.
Sometimes it may be inevitable as i.e. only Release version of some external library may be available. Hence in VC++ there are linker settings allowing to ignore some specific libraries. So you may start checking in the Linker-Input settings of the Debug build if such ignores are already defined for existing conflicts. With some luck you might be able to remove them now.
If using the Debug version of some library breaks the whole program it might be an insight how to improve the whole system, it is that what a Debug build is for anyway.
Assuming that it is the right library (as in the same code compiled to a different configuration), you are right to link to the debug dll on your debug configuration (and should link to the release dll on your release configuration).
The differences tend to be related to the optimisation level (Debug is usually compiled without any optimisation at all) and any symbols that might be included to make it easier to develop with and maybe step into.
I have a mfc c++ project on vs2010.
I am able to build it in both debug & release mode , but when I run it in debug mode, it gives the follow mfc100d.dll error. I have also installed C++ runtime environment vcredist_x86.exe still the issue is not fixed. Also I have set the Multi-threaded DLL (/MD) as the Runtime Library.
How do I fix it ?
The d suffix on the name of the DLL indicates that it's a debug version of the runtime DLL. That's confirmed by the fact that you say the problem happens when you try to run the debug version of the application.
By default, and for good reason, debug builds link to debug versions of the runtime libraries. These versions are not redistributable, and thus are not getting installed with the redistributable package (vcredist_x86.exe). That's not normally a problem: you aren't supposed to ship debug versions of your application.
The non-redistributable debug libraries are, however, installed with Visual Studio, so the debug version of your app should run fine on the computer you used to develop and build it. Which is likely the same computer you're going to use to debug it.
Also I have set the Multi-threaded DLL (/MD) as the Runtime Library.
Three important things to note about this:
You have to make sure that you set it for the correct build configuration (i.e. "Debug").
This is not recommended. Debug builds of your application should use the debug versions of the runtime libraries. They do a lot of things behind the scenes that help you to catch bugs. That's why they exist. If you don't want a dependency on the debug version of the runtime libraries, compile and distribute a Release build of your application.
That switch changes the version of the C/C++ runtime library that your application links to. The DLL you're getting the error message is an MFC runtime library.
The MFC headers test whether the _DEBUG preprocessor symbol is defined in order to determine which version of the runtime libraries should be linked in. Since _DEBUG is defined automatically in a debug build, it's linking in the debug version of the MFC libs.
To change that, you're going to need to do a lot of manual labor, undefining this symbol before you include the MFC headers, and then re-defining it afterwards.
Alternatively, you can statically link to MFC, which is a setting in your project's properties. But do be careful with this: you'll end up inadvertently mixing versions of the CRT, which can leave you in a world of hurt. Better to just ship release versions and keep debug versions for internal debugging.
Reinstalling the Microsoft SDK fixed this error.
Is it possible to execute debug mode DLL with release mode EXE?
I am trying this scenario but EXE does not load the debug DLL and throws error "This application has failed to start...".
I know this is not good scenario to do but Due to certain requirements I have to make this work.
It can work if your dll interface has no dependencies on classes that may look different in debug and release.
e.g. std::string and std::vector in MSVC are not compatible in debug and release. (Fences ...)
So for example
std::string GetName();
will not work.
In additional new and delete should not be shifted because debug/release use different runtimes. But anyway you should always delete in the same context(dll/exe) as new.
Yes, this can work.
Your "application has failed to start" issue is most likely you copied a debug build of the DLL (built on your machine with Visual Studio), to a machine that did not have the DEBUG CRT installed. Usually copying over MSVCRTD(version).dll to the same directory as your program files solves this problem. I have a previous answer that covers some of this here.
Best bet is to always have all your binaries linked to the same dynamic MSVCRT DLL so they all share the same runtime.
Another easy workaround is to compile your DEBUG DLL to use the same flavor of the MSVCRT DLL (or statically link to the CRT). Somewhere in the VS project propery pages (code generation I think) is the dropdown for choosing the CRT. There's nothing wrong with linking the retail MSVCRT into a debug DLL - or statically linking.
The things to watch out for are when you have a different flavor of the debug C runtime linked to the different binaries. If you have the release MSVCRT dll linked for the EXE, but the debug MSCVRTD DLL for the DLL, that can cause problems in a few circumstances. This is because handles and memory blocks are tracked by two different instances of the CRT.
Examples:
If you allocate memory in the EXE, but free in in the DLL. And vice versa.
File handles opened with fopen() in the EXE, but used or closed in the EXE (and vice versa).
For any of the header files for the DLL's interface, having any sort of inline functions or methods implemented in the header file is an easy way to cause #1 or #2 to happen.
Sharing STL objects (std::string, std::list, std::vector) is a definite no-no for mixed CRT usage.
I have a dll that I distribute that will not run on some windows OS. Using dependancy walker I discover msvcp90d.dll missing on these systems. I DO NOT want any run time dependancies that require the C++ redistributable, and since the application that calls the DLL is not written in C++, it does not have any dependancy on the C++ redistributable.
I am guessing the I left the DEBUG option in the linker preferences on when I compiled the dll which is why it needs msvcp90d.dll?
ADDED:
Appologies, I pasted the wrong dll name in my original question.... too many hours in front of the monitor...
THe dll is a third party dll that I did not write compiled by me in VS2008.
MSVCP90 is nothing to do with debug (that'd be msvcp90d). You can remove your dependency by switching the compiler to /MT (instead of /MD). You also need to ensure that every static library you link to was also compiled /MT.
I recommend against building apps /MT because it has a significant negative effect on system performance and makes servicing take longer in the event of a security issue with the CRT.
Finally, note that /MT means that your CRT is private. So you must ensure that CRT/STL types don't pass across your DLL boundary.
Martyn
Your options as I see them:
Compile the DLL with the /MT option to use static linking to the C runtime.
Continue with dynamic linking to the runtime, but distribute the C runtime with your app.
It needs MSVCP90.dll because the dll was compiled with Visual Studio 2008 most likely. That is the release runtime. The short answer is if you don't want C++ runtime dependencies don't use C++ libraries or applications.
However you can do any of the following to solve your problem:
Install the redistributable to the target system to satisfy the dependency
Remove the dependency on that dll from your application
Recompile the dll against the version of VC you prefer that is already present on the target system
I have an application I'm working on that uses two third party libraries, each with pre-compiled libs and dlls, one of which provides necessary .lib files for both debug and release builds (A[d].lib) and the other which provides only .lib files for release builds (B.lib).
Compiling in Release mode (using MSVC9) works fine, however attempting to compile in debug mode fails because third party A requires LIBCMTD.lib (or MSVCRTD.lib) while third party B requires LIBCMT.lib (or MSVCRT.lib).
Can I work around this or am I stuck debugging in release mode?
Do you want full debug mode, or do you just want to be able to debug? If the later is the case, just go to the linker options, and turn on the generation of symbolic information (.pdb). This way you can use the debugger in your own code, step through the lines, and look at variables. If you get annoyed by the changes in control flow that the optimizers create, you can go to the compiler options, and turn off optimizations. This way you get to use the debugger AND build in release mode. Once you're happy with your code, you just change the settings back to creating optimized code.
Try passing /NODEFAULTLIB:LIBCMT to the linker.
I am not sure it can be done directly with static libraries. I suggest you package library B into a dynamic library, then use this new B' library. Your problems will have disappeared.