There is a lot of confusion over the various runtime libraries provided by Microsoft for C++ programming. On this page I will attempt to explain the different libraries and when they should be used and also discuss the new manifest files.
Static (.lib) and Dynamic (.dll) Libraries
A static library is one that is linked at build time. This means that all the code from the library is inserted into your executable. This makes your executable much bigger in size but has the advantage that it does not depend on external dynamic libraries being present on the host machine (or being of the correct version). Static libraries normally have the .lib extension.
A dynamic link library (dll) is one that is linked to at run time. This means the code from the library is held in a dll file on the host system. When your executable runs it loads this dll (note that you often have to link to an import .lib file that handles the opening of the dll). There are a number of advantages to this approach. Firstly any changes to the library e.g. bug fixes can theoretically be applied just by updating your dll file rather than having to update the whole executable. E.g. if Microsoft fix a bug in a common dll then all applications that use that dll will benefit from the fix. Those that were linked statically would not benefit. Secondly the code for common functionality only needs to be loaded once into memory however many applications are using it. E.g. Microsoft provide a common library for file open / browse / save dialogs and functionality. Many programs use this functionality but however many are running at a time only one library with the code needs to be loaded into memory. Finally your executable is much smaller in size.
C / C++ Runtime Libraries
The compiled code for the C / C++ runtime libraries are held in the different files below. There are different versions for release and debug libraries and also for single and multithreaded libraries. Note that these libraries do not contain the C++ Standard Library code e.g. things like string or vector etc. The code for those is held in the libraries listed in the Standard C++ Libraries section below. The command switch will lead to the loading of one C runtime library and, if you include a standard library header anywhere in your project, one C++ standard library.
|Static library to linked to||Vis 2005 build associated DLL||Previous Versions||Comments||Command|
|libcmt.lib||Multithreaded static link.Note: previous versions of Vis also had a libcimt.lib (and debug libcimtd.lib) libraries with iostream functionality.||/MT|
|libcmtd.lib||Debug version of above||/MTd|
|msvcrt.lib||msvcr80.dll||msvcrt.dll and msvcirt.dll (All previous version of Vis)||Multithread dynamic link library. Import library for the loading of the dll at runtime.Note: previous version of Vis also had msvcirt.lib (and debug msvcirtd.lib) libraries with iostream functionality.||/MD|
|msvcrtd.lib||mscvr80d.dll||msvcrtd.dll and msvcirtd.dll (All previous version of Vis)||Debug version of above.||/MDd|
|msvcmrt.lib||msvcm80.dll||Used when you wish to mix native and managed code. Import library for the loading of the dll at runtime.||/clr|
|msvcurt.lib||mscvm80.dll||Used for pure managed code. Import library for the loading of the dll at runtime.||/clr: pure|
|libc.lib, libci.lib||Single threaded static link (deprecated)||/ML|
|libcd.lib, libcid.lib||Debug version of the above (deprecated)||/MLd|
C++ Standard Libraries
The C++ standard libraries are extra libraries of useful functionality you can use in your C++ code e.g. iostream, vector, string, lists etc. Note that these are included if you use just one header from the standard library.
|Static library linked to||Vis 2005 build associated DLL||Previous Versions||Comments||Vis Command Switch|
|libcpmt.lib||Multithreaded static link||/MT|
|libcpmtd.lib||Debug version of above||/MTd|
|msvcprt.lib||msvcp80.dll||msvcp71.dll (Vis 2003) ,|
mscvp70.dll (Vis 2002),
scvp60.dll (Vis 6.0),
mscvp50.dll (Vis 5.0),
msvcprt.lib (Vis 4.2)
|Multithreaded dynamic link. Import library for the loading of the dll at runtime.||/MD|
|msvcprtd.lib||msvcp80d.dll||msvcp71d.dll (Vis 2003),|
mscvp70d.dll (Vis 2002),
mscvp60d.dll (Vis 6.0),
mscvp50d.dll (Vis 5.0),
msvcprtd.lib (Vis 4.2)
|Debug version of the above. Import library for the loading of the dll at runtime.||/MDd|
|libcp.lib||Single threaded static link. Note that this is now deprecated and no longer supported by Visual Studio||/ML (deprecated)|
|libcpd.lib||Debug version of the above||/MLd (deprecated)|
In Visual Studio the runtime and standard C++ library is chosen via a command switch. This can be set via project properties / C++ / Code Generation / Runtime Library:
No more single threaded libraries
The libc.lib, libcd.lib, libcp.lib and libcpd.lib libraries are the old single threaded libraries and are no longer supported by Visual Studio. This may seem annoying at first but in fact most target platforms are now going multiple core or multiple processor and so the future is very much with multithreaded programming. Microsoft believe the performance of the new multithreaded libraries is now close to that of the old single threaded ones but have provided some methods to improve the performance of applications that operate in a more single threaded way e.g. defining _CRT_DISABLE_PERFCRIT_LOCKS forces all I/O operations to assume a single threaded I/O model. See the further reading link for more details.
The dynamic linking approach via dll libraries seems ideal however problems can arise when changes to the dll cause problems with the original executable. You can then end up in the situation where executables need different versions of a library. This is why sometimes installing one application can break an already installed one. To attempt to fix this Microsoft have introduced manifest files which detail which version of the library should be used e.g. below is a an example manifest file:
<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
<assembly xmlns=”urn:schemas-microsoft-com:asm.v1″ manifestVersion=”1.0″>
<assemblyIdentity type=”win32″ name=”Microsoft.VC80.DebugCRT” version=”8.0.50727.762″ processorArchitecture=”x86″ publicKeyToken=”1fc8b3b9a1e18e3b”></assemblyIdentity>
Each dependency is detailed by its name, version number and processor architecture. The actual library files are held in your windows directory in a sub directory called WinSxS. Within this directory there is a directory whose name is created from the data above e.g. for the above the directory will be in directory: “amd64_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_869ab37f”. Note that you can no longer simply copy a Microsoft dll file to your Windows folder but must install it properly.
Manifest files can either be embedded in the executable as a resource (RT_MANIFEST) or provided with the executable (in the local folder). In general you should embed manifests and this is the default setting in Visual Studio. When you build a project you will see one or more temporary manifest files in the build folder e.g. appName.exe.intermediate.manifest, appName.exe.embed.manifest and a resource one called appName.exe.embed.manifest.res. If you open the resource one you will see the resource (RT_MANIFEST) along with an id. The id should be 1 for an executable and 2 for a DLL.
Common Library Problems
Common linker and runtime problems occur when there is a mismatch of linked libraries e.g. you could be linking with multi threaded and single threaded which do not mix. Other problems occur when your are linking to a static library that has been linked with different versions or created with previous version of Visual Studio. End user problems can be down to missing library files.
The best way to determine the full set of dependencies for an application is to use the depends application that is provided with the platform SDK (depends.exe). This application allows you to load executable (exe) or dynamic link library (dll) files and produces a full set of dependencies.
Often the solution to a run time problem is for the end user to install the latest .NET framework from Microsoft.