I understand that it is all quite confusing and most of it is so basic that the Microsoft documentation is probably not clear.
When building a compiled program, there are two basic phases that are important and relevant. They are
compiling and linking. Nearly all compilers depend on a separate link step. Compilers have worked this way for nearly half a century.
Another thing that is important to understand is that a lib file is used by the linker only. A lib file is never used at execution time. A lib file is only for use by the linker to find things and to know how to use them.
For roughly the first quarter of a century all linking was static. That means that all machine code for a program was put into one file, which is the equivalent of a Windows exe file. If a program called a subroutine then the machine code for the subroutine was included in the one file. The problem with that is that if a subroutine is changed then every executable file that uses that subroutine must be re-linked.
For most compiled languages, including C/C++ especially, a source code file can
include multiple subroutines (functions) that are compiled to a single object
(".obj") file. In a Windows environment it is possible to create a
library (".lib") file with information about multiple subroutines
(functions) in a single or in multiple object files.
For static linking a library file just makes it easier for us by reducing the parameters necessary for specifying for the link editor. (I know that last sentence is not written well.) For static linking it is possible to have multiple object files and all could be listed as a
parameter for the linker or information about all object files could be combined into a library file.
The advantage of dynamic linking is that if a subroutine is changed then any executable file that links to it dynamically does not need to be changed, unless there is an obvious change to the subroutine such as the number and/or type of parameters.
For dynamically linking a library file contains linking information for all
functions that are exposed by a DLL file and (I think but I am not totally sure
that) the linking information is always for just the one DLL.
In a Windows environment it is uncommon to make a subroutine (function)
callable either way; usually a subroutine (function) can be called either
dynamically or statically but not either/both ways.
What happens when a program is compiled and an exe file built is that:
- the resources are compiled into a .res file
- each .cpp file is compiled into a .obj file
- the linkage editor combines the .res file and all the .obj files into an executable file