Conceptual ambiguity between "/MD /MT " and "dll lib" - c++

I am perplexed by the concept between the run-time library option on Windows. I thought I know the difference between lib and dll. The lib will be compiled to your code and the dll will be loaded dynamically on execution. But when I compile a lib, I am obliged to make a choice between /MD and /MT. On msdn.microsoft.com it is said that:
Applications compiled with /MD are statically linked to MSVCRT.lib.
This library provides a layer of code that enables the linker to
resolve external references. The actual working code is contained in
MSVCRversionnumber.DLL, which must be available at run time to
applications linked with MSVCRT.lib.
At this time I cannot catch the idea that when I using a lib I also need to dynamically load a dll. It seems like that using /MD option to build a lib will result in a "dynamical lib", or using /MT option to build a dll will result in a "static dll".
So what's the difference between "/MD vs /MT" and "lib vs dll"?

A key aspect of this is differentiating between the build/compile time issues and the runtime issues.
At build time, the compiler and linker need sufficient information on how to compile and construct the code; data definitions, function locations etc. The header files provide most of that detail for the compiler, the linker needs to be able to locate the functions1 to complete the process.
If the dll is provided with a lib as well (as is the case with /MD), this lib contains the minimum required code for the linker to find the functions required and some additional code to load the dll at runtime. A program can be made that does not link with a lib (even though there is a dll), you will then need to load the dll at runtime (via LoadLibrary) and fix up the pointers (via GetProcAddress) to the functions1 you need to call. With a C++ library that is difficult, hence it is generally not attempted, the name mangling make this harder (with a C library it is generally much easier).
If the lib is a static lib with no associated dll (for the runtime this is /MT), then the lib contains all the code needed to run and execute its given functionality. The linker links all the required code up into the target and no additional runtime loading is required.
1 I loosely use the word functions here, but it includes all externals as well.

In both cases the application will be statically linked with a .lib file, but if /MT is used then it will be linked with libcmt.lib or libcmtd.lib (Release/Debug), which contain the C run-time itself, whereas if /MD is used it will be linked with msvcrt.lib or msvcrtd.lib, which are just import libraries for the DLL and do not contain the run-time.
See https://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.120).aspx for details.
(Note that in VS2015 the libraries have been split and have new names; the C99-portion names are libucrt.lib, libucrtd.lib, ucrt.lib, and ucrtd.lib, respectively.)

Every DLL has a corresponding .lib file too. The linker links against the .lib file, which has the necessary instructions that indicates which symbols need to be loaded at run time from a DLL.

Related

why there is a .lib file when create dynamic .dll file?

I'm try to build a dynamic dll library on on windows using visual studio, but there are two file generated, one is dll file, another is .lib file;
My knowledege of using dll library is privode it to linker, I don't know what is ther purpose of .lib file, it has the same file extension as static lib, and it definitely is not static lib;
Does visual studio generate a .lib file when create dynamic dll library at all situtation?
Do I need to use the .lib file in my application?
How do I do use the .lib file in my application?
It has to do with the difference between "implicit" linking and "explicit" linking. The one sentence answer to your question is that that .lib file, often called a "stub lib" and officially called an "import library", is necessary when you do implicit linking but not otherwise.
In implicit linking, at compile time the compiler generates external function references for calls into the DLL, then the linker needs to link those to something: it uses the import library to help it do that. The linker treats these calls as special cases; it inserts code in the executable file for finding the DLL and for calling into the DLL for specific functions.
From the point-of-view of the programmer, implicit linking behaves like static linking except the DLL needs to be somewhere where the system can find it when the application is run or the system will pop up an error dialog at application startup.
Explicit linking means that it is the programmer's responsibility to find and load the DLL and to know what functions are in the DLL and how to call into them. See LoadLibrary and GetProcAddress for details. Explicit linking is useful if usage of a library is conditional or for applications with plugin architectures in which the actual DLLs to be used may not even be known at compile time.
In general though, if implicit linking does what you need, it is easier to just do it that way.

Avoid runtime dependency with a dll using runtime DLL (/MD)

We use VS2012, and have a dll built with a dependency on runtime DLL (/MD).
This dll is used in many different projects, and cannot be changed easily.
We also have a small launcher executable that has to able to run on freshly installed systems, hence with no runtime installed. It is linked statically against the runtime (/MT).
Now this exe depends on the above dll.
As is, the exe does not built [1]. I have observed that building it by ignoring MSVCRT (/NODEFAULTLIB:"MSVCRT.lib") solves [1], but produces [2].
Adding the few symbols reported as errors in "force symbol references" (e.g. /INCLUDE:"_strncpy") makes the build succeed.
However checking the generated exe with Dependency Walker shows the dependency to the runtime DLLs [3] through our dll. I confirmed that the strings [3] are present in it. Trying to run the exe on a clean install of Vista fails (the error says a DLL from [3] is missing).
I fear that this is not possible, and I have not found any information that suggests that it is.
Can a statically linked exe provide runtime functions to a dynamically linked dll? If yes, how?
Thanks
Refs:
1>MSVCRT.lib(MSVCR110.dll) : error LNK2005: _sprintf already defined in libcmt.lib(sprintf.obj)
error LNK2001: unresolved external symbol __imp__strncpy
MSVCP110.dll, MSVCR110.dll
Yes, a statically linked exe can provide functions to a DLL. However doing so with the Standard Library functions is more trouble than it is worth.
You'd need to stop the DLL from building using its own copy of the runtime, using /NODEFAULTLIB. That will get you a bunch of link errors, since every part of the Standard library, as well as some vendor extensions, used by the DLL is now an unresolved external.
Each of these would need to be added to the EXE exports tables, using a module definition file. An import library would be generated during EXE linking. And then that import library would be supplied to the DLL to satisfy its externals, resolving them.
In the end, you would have only one copy of the runtime library, allowing your EXE and DLL to share library objects such as FILE* and the heap (so you could allocate in one and free in the other). But the DLL and EXE would be extremely closely coupled. Almost any change to the DLL could break the build, and require new exports from the EXE to fix it. You definitely could not ship updates to the DLL separately from updates to the EXE.
A much easier approach, that still keeps the DLL size down, would be to use delay-loading. This way, although the DLL still cannot load without the runtime redistributable installed first, the failure would not occur during process startup, and the EXE would have a chance to check for the presence of the runtime and install the redistributable. Or diagnose and handle failure of the DLL to load.
In an extreme case, the EXE could avoid using the Standard library at all, ensure the presence of the redistributable components, and then invoke the delay-load DLL for all complex logic requiring the Standard library runtimes.
In these latter cases because the EXE is not using the DLL version of the runtime, you can't share Standard library objects between EXE and DLL. But the coupling is much much looser. I think it's a tradeoff worth making.
We eventually changed our dll build settings to /MT.
I don’t know of any other way to solve the problem.
If your .exe needs to run on a clean OS, it can't depend on any DLL's that are dynamically linked because these DLL's (and thus the .exe) can't load without the runtime DLL's. Have you considered an app-local deployment? Then both the .exe and dll can be built with /MD.
It is possible to create a project that can build as either a DLL or a static library. The small launcher executable should link with the static library configuration of the DLL project.

No additional dependencies required for a LIB but are required for a DLL

I have a framework (in C++) which is dependent on a few third party libraries. When I compile a static version of the library framework, no additional dependencies are needed, that is, the lib files of the third part libraries are not needed. When I compile the same framework as a DLL, additional dependencies are now needed otherwise I get linking errors. I can guess as to why this is happening but would like a concrete answer/explanation to understand what is happening.
EDIT: Just to clarify, I am developing a framework which can be compiled as a lib and as a dll and then used in a(n) (executable) project. When compiling the framework as a lib and using functions from a third party library, I don't need additional dependencies. However, a project that now uses the lib file (which is the framework) must include the 3rd party lib files. When I compile the framework as a dll it gives me linking errors unless I specify the 3rd part libraries the framework is technically dependent on. For example: I have a few classes that call functionality from within Ogre3D. These classes are compiled as a lib file. I don't need to link against OgreMain.lib when compiling a lib of the classes. On the other hand, when I am compiling a dll version of the same classes, I now need to link against OgreMain.lib
When you have a static library (a .lib file), which is just a collection of one or more object files (.obj), the linker just adds that code to yours in one executable. You can tell the linker to do this via a command line switch, an IDE configuration setting, or perhaps even a #pragma (specifics depend on your environment and compiler).
When you link in a DLL, you need to give the linker some code to call when you invoke one of the DLLs functions. Usually, this is done with a file of the same name as the .dll, save that it is a .lib. The code in that .lib is linked into your program the same way as described above, but when you call it, it loads the DLL (if not already loaded) and then invokes the proper function.
There are other ways to handle DLL linking (for instance, .def files or #using statements in .NET), but this seems to be what you're talking about.
Responding to your question clarification:
The issue is that a .lib is not a final product. It is just an aggregation of object code to be used later when a linker connects all your functions calls to function addresses.
A DLL, on the other hand, is a final product, and so the linker requires all functions and variables be connected to actual addresses.
I'm speaking a bit imprecisely, but you get the idea.
A static library can include other static libraries, providing a single lib to link
A DLL can include static libraries, providing a single DLL to link.
A DLL or static library with dependencies on other DLLs has no way to combine them so your executable must explicitly link to those other DLLs.
When you link to a LIB it adds all the symbols/functions you actually use to your executable. The ones you don't use won't get added. When you link to a dll - all the code from the external library gets loaded. If this additional code (code you don't use) depends on more external libraries you need to provide these as well.
One example: You want to use a ip class from a network library. The ip class does not depend on other libraries. Other functions in the network library depend on other external libraries. If you link the network library as a LIB you just link the ip class -> you don't need the other libraries since the other code wont get linked. When you use the DLL all code in the dll need to be instanciated -> so you will need to provide the other external libraries.
Building a DLL is more like building an application than a library. The difference between building an application and a DLL is knowledge of what might be called. In an application all symbols that are not used can be discarded in the build, but in a DLL you cannot strip symbols that are not used - that would be all of them...
You would find the same link problems in your static libraries if you where able to call all the symbols that the DLL links.

How do I find the cause of this linker error?

After going through a lengthy process to rename a project, my DLL project will not build in Debug mode (Release builds work):
MSVCRTD.lib(msvcr90d.dll) : error LNK2005: _CrtDbgReportW already defined in LIBCMTD.lib(dbgrpt.obj)
This project, and the five static libraries it depends on, are set to use "Multi-threaded Debug (/MTd)" (under C/C++|Code Generation|Runtime Library). I believe LIBCMTD.lib is the one for multi-threaded debug, but what is MSVCRTD.lib, and what could be causing this error?
If it makes a difference, this DLL is for Windows CE.
LIBCMT is what you need for /MT, MSVCRT is what you need for /MD. You are linking .obj and .lib files that were mixed, some compiled with /MT some with /MD. That's not good.
Usually it is the .lib files that cause the problem. Review their build settings and make sure their /M option is the same as your DLL project.
Also, beware of the trouble you can get into if the DLL was compiled with /MT. You'll have major problems when the DLL returns pointers to objects that the client needs to release. It can't, it doesn't use the same memory allocator.
The MSDN article on LNK4098 has a very useful table: it tells you which libraries to manually add to the "Ignore specific library" list, depending on which CRT you're using. In your case, you should ignore all of these:
libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib
Observe that the reported library is in this list too. The problem is described in more detail in KB154753 ... libraries that a program will link with when built by using Visual C++
My interpretation of this is that in certain situations the algorithm that automatically picks which CRT libraries to link your code with will pick several conflicting libraries.
What is release set too? Setting a DLL to multithreaded debug can cause problems if you allocate memory that something accesing the DLL tries to free (they will be allocated in different heaps, for example). Try setting multi-threaded debug DLL.
Your link problem probably arises because a library you are linking to is expecting multithreaded debug DLL so the linker tries to link both and your link fails ...
The problem is the msvcr90d.dll is not in the windows ce image. It must be deployed with the application. The msvcr90d.dll is located in $(VCInstallDir)/ce/bin/$(ARCHFAM).
http://stackoverflow.com/questions/15959877/windows-ce-6-0-and-runtime-link-to-debug-dll-mdd

Linking with both static and dynamic libraries in MSVC

I am working on a c++ project that links to a static library. However, I want to use intel's TBB, which is only available as a dynamic library. I tried to set this up in visual studio but I can't get it to work. Does anyone have detailed directions to do this if it is possible?
Typically when a library is made available as a dynamic library (.dll), it also comes with a .lib file to link against (as discussed in this question). This can be added to the project's list of inputs the same way that a static library is
Project Properties->Configuration Properties->Linker->Input->Additional Dependencies (in VS2008)
If a .lib is not available, then you'll have to load the .dll at runtime using Win32 API function LoadLibraryEx and then subsequent calls to GetProcAddress to get the addresses of the functions you need.
Are you talking about linking to a RUNTIME library? No you can only link to one. You have to either change your project, or you have to recompile the TBB to link to static runtime as well.