Hello all,

I am a little confused about .lib and .dll files. I always thought that .lib files refer to a static library and that a .dll is the dynamic library. Recently, i read that .lib files also act as a stub for a .dll and that the .lib files are used by the linker in order to load the dll into memory.

Now, i'm confused as to what are these lib files. Also, when I download binaries for libraries, say a library for loading jpeg images, i generally get a .lib and a .dll file. And in the linker options for the IDE, I would set the .lib file as a dependency.

Now, i'm not sure as to what those .lib files are, and what exactly is the difference between the two.

Can anyone please clarify this for me?

Thanks a lot!

First, the obvious, in both cases, you have compiled code, so it is all a matter of linking and loading.

In all cases, a .lib file is a static-link library, meaning that it is used by the linker to complete all the function calls that exist in your application that refer to functions in that library. At the end, the linker grabs all the compiled code from the library (only the functions that are actually called at some point) plus all the compiled code from your program, and bundles everything into an executable file. So, we call it statically linked because all the links between function call-sites and the blocks of compiled code for those functions are accomplished before the final executable is created.

Now, when you actually run an executable, the operating system has to do a number of things, of which I won't mention too many details. Basically, the OS has to "load" the executable, giving it a chunk of memory to work with and a virtual address space to address that memory. Then, the executable itself runs a certain amount of code to initialize itself as well, and then the "main" function starts executing.

In many ways, a DLL is conceptually more closely related to an executable than it is to static library. A DLL, like an executable, has to be loaded by the operating system which gives it a place to live in the system's memory, and allows it to run some initialization code as well. The difference is that a DLL does not have a "main" function, but, instead, has a bunch of functions that are published (or exported) and can be called by other applications. Another special thing with DLLs is that they share the same virtual address space as the application that is using it. This means that everytime an executable (or another DLL) requests to use a given DLL, then the OS will first check that it is loaded (if not, the OS will load it) and then it will create a kind-of bridge between the virtual address space of the executable and the DLL, so that whenever a call to a function of the DLL is initiated by the executable, that function will get executed in the same address space (otherwise it wouldn't work). So, a DLL is called a dynamic-link library because the link between the executable and the DLL is achieved when running the application.

Anyways, all this is to say that loading and using a DLL is a task that requires a certain amount of work "under-the-hood". Now, you have two choices with regards to _when_ you do this task: at load-time or at run-time. What this means is that you can either load the DLL as part of the process of loading your executable (in the initialization code of the executable), or you can load the DLL at any given time during the execution of the application. In the latter case, you use functions like "LoadLibrary()" to load the DLL, "GetProcAddress" to get a function-pointer to a specific function in the loaded DLL, and finally "FreeLibrary" to un-load the DLL once you no longer need it. In the former case, at load-time, the executable basically has to do the same, but automatically (before the main function starts). So, as part of the initialization, a certain amount of code runs in order to ask for the DLL to be loaded and to retrieve all the necessary function-pointers from it. And that's the code that is in the .lib file which comes with the .dll file. It's as simple as that. That static library simply contains all the code necessary to load the DLL and link all the functions at load-time (such that you don't have to do it manually with "LoadLibrary" and "GetProcAddress").

Edited 5 Years Ago by mike_2000_17: n/a

in mingw and mingw-w64 and borlandc++ and vc++'s case, you can link to winuser.h and libuser32.a/user32.lib and this library is tied to a user32.dll that comes with windows, it is not static. in fact, there are many such libraries. the ABI's are such now that DLL's (maybe also shared libraries in general) must be used for stdc++ for mingw or gcc with the new version.

linux also has shared libraries, these are .so files and the library you link to is a .a since it's probably going to be gcc.

the previous answer I think is mostly correct, about everything except that maybe the library is static. I am not entirely sure about that one. the acronym "DLL" means Dynamic Link Library. it is possible that the .lib/.a library you are linking to may indeed be a static library, but what do you call it now that it is tied to a shared library such as a DLL? is it still called "static"? or is it really called "dynamic", or is it only the DLL/so itself that is called dynamic?

>>what do you call it now that it is tied to a shared library such as a DLL?

The .lib / .a file that makes the link to the DLL is called an "import library", and it is indeed a static library (albeit a special kind of static library). It is just a static library that contains an amount of code to import the DLL at load-time, in other words, it acts as the "middle-man" between your code and the dynamic library.

>>is it only the DLL/so itself that is called dynamic?

Yes. Except that .so files are not usually called dynamic libraries, they are either called with the general term "shared library" or with specific term "shared object file". DLLs and shared-objects are actually very different because the dynamic linking models used by Windows and *nix systems are very different, and in fact, in *nix systems you don't need an "import library" to link to an .so file (but in MinGW in windows, you need a .a file to use a DLL).

Thanks for the detailed explanation Mike :)

At the end, the linker grabs all the compiled code from the library (only the functions that are actually called at some point) plus all the compiled code from your program, and bundles everything into an executable file.

Now, where exactly is that compiled code placed in? I used to think that the compiled code is the one that is present in the .lib file. Could you clarify that for me?

Thanks!

the .dll/.so and the .a/.lib are both compiled files. what exactly do you mean?

DLLs are placed in the execution PATH. sometimes in c:\windows\system32 (a bad place because it's hard to uninstall) but usually you put it in the same directory as your .exe

the .lib import library files are compiled I think using .def files to define the interface.
DLL's have a DllMain() for initialization purposes (I know you are not supposed to start threads in it).

libs are handled the way your compiler likes it to be handled. usually there is a LIBRARY_PATH or some other environment variable you need to set, or a commandline switch you need to set to add a library directory/directories to the library path so the compiler can find your set of custom libraries. you set this in your application's build environment, such as a makefile (in my case, I use batch files).

Edited 5 Years Ago by jmichae3: n/a

I'll take a stab at this, but others please correct me if I'm confused. There are two potential paths to take when -creating- a library ... static vs. dynamic.

If you create a "static library", you end up with a large .lib file which contains all the compiled code for the functions in that library. If you then create an executable using that library, all of that code is copied into the executable at link-time (compile-time: when source code is analyzed and turned into compiled object code, link-time: when various object files and libraries are "linked together" to create the final executable). This makes a larger executable, but one that doesn't depend on a separate DLL file at run-time.

If you create a "dynamic library", you end up with a large .dll file and a small .lib, as previously described. All of the compiled code for the functions in the library is in the .dll file. Now your final executable is smaller, since the code is -not- copied into the executable at link-time, but the .dll file has to be sent along with the executable, unless you can rely on it already being correctly installed on the end-user's computer.

The advantage of dynamic/shared libraries is that many different programs which need the same set of functions can all get that code at excutable load-time, rather than having that compiled function code copied into each executable. In addition, this is mostly how "plugins" are handled -- except now a program can use LoadLibrary() and the other functions described above to load compiled code from .dll files only once it determines it needs that code (i.e., the user specifies he wants to use a given plugin). Also a well-designed plugin system allows the creator of the original program, or even third-party developers, to create new plugins that the program can still use, even though those plugins didn't exist when the program was written and shipped.

the DLL is useful when you have multiple executables which share a common API (what the DLL exposes as its functions). typically, with a DLL, you extern "C" {} them so as not to C++ name-mangle them and thus make them compatible with other languages like Java, Fortran, Smalltalk, etc.
that's the other use of DLL's - as a common language interface for your API.

Thanks a lot raptr_dflo, jmichae3, Mike.

>> If you create a "dynamic library", you end up with a large .dll file and a small .lib

I was confused as why there is a .lib file created when a dll is created. Now its clear.

Thanks!

This question has already been answered. Start a new discussion instead.