.lib / .a and .dll / .so files are seen everywhere, from the OS to custom programs.
Their purposes are multiple and understanding what they are can help you build and use them more efficiently.

What are those ?#

Both types contain compiled code and data which can be used by your own program.
Their uses are multiple, such as :
  • code reuse - with DLL / SO files, you can easily build once - use multiple times the same code along various projects.

  • sharing obfuscated code - since the code is already compiled, it is nearly impossible to retro-engineer it. Thus, you can allow someone to reuse it without impacting your intellectual property on the file.

  • plugin system - for non-interpreted languages (such as C++), it allows your code to be extended with the final user’s handmade code.

  • smaller rebuild and easier update - since the code can be directly used, cutting your project into multiple subfiles allows you to rebuild only the required parts of your project, decreasing the build time. Also, if you’d like to update some parts of your project, you can modify and transmit only the concerned parts.

All or a small portion of the code it contains can be given out thanks to header files. Without them, it will be nearly impossible to use.

.lib / .a - the static libraries#

.lib (Windows) or .a (Unix) files are known as static libraries.
Static libraries are called so since the code they contain is used during the compilation process, copied into the binary directly.
I.e. : if A.exe and B.exe are built against a .lib file, both will contain all the used code from within the library.

Sometimes, such files are found along with dll / so ones. Please read the next chapter.

.dll / .so - the dynamic libraries#

.dll (Windows) or .so (Unix) files are known as dynamically linked / shared libraries.
Those libraries can be loaded and unloaded on the fly during the run-time of your application (e.g. if you do not use some sub-modules, you can preserve memory while not loading them).
Also, they can be shared between multtiple programs. Following the program, their path should be put into the PATH variable or inside a specific folder.


The data is NOT shared between the programs. If a .dll contains a string, it will be created on the program stack or heap memory.

Implicit and explicit linking#

Sometimes, along with such files, you will find their “static libraries” companions (.lib, .a or .def). Those libs do not contain code, but rather some description (adresses, entry point …) on how to call and use the library.
This process is known as implicit linking. With the appropriate headers, you just have to pass the .lib / .so files to the linker.

If not provided, it will be harder to work with, by manually finding exports (addresses) to call the functions through pointers.
Such process is known as explicit linking. You may need to work as is while working on multiple, not predefined libraries (such as plugins), or for reverse engineering process.




Embedded code (during compilation)

Linked at run-time (program execution)

Not recompiled, but copied in each program

Can be used by multiple programs (no data sharing)

No versioning issues (as code is not shared between apps)

A program installing a newer or older version of the same library may make other programs crash

Faster run since the code is embedded

Slower execution while the libraries are loaded

Bigger memory use, as the whole code is embeeded

Cut into multiple files that can be loaded and unloaded on the fly

Can sometimes be a helper to load DLL files, containing entry points

DLL LIB Libraries