1

LIB files are static libraries that must be included at compile time, whereas DLL files can be "dynamically" accessed by a program during runtime. (DLLs must be linked, however, either implicitly before runtime with an import library (LIB) or explicitly via LoadLibrary).

My question is: why differentiate between these file types at all? Why can't LIB files be treated as DLLs and vice versa? It seems like an unnecessary distinction.

Some related questions:

DLL and LIB files - what and why?

Why are LIB files beasts of such a duplicitous nature?

DLL and LIB files

What exactly are DLL files, and how do they work?

PProteus
  • 549
  • 1
  • 10
  • 23
  • 2
    Because to allow the dynamic linking the object file, a DLL, need accessory structures not required by a static lib (i.e. import tables and export tables). This necessarily lead to different object contents (they aren't the same object!). – Frankie_C Jul 03 '20 at 12:36
  • @Frankie_C This should be an answer. – yugr Jul 04 '20 at 04:37
  • @yugr Thanks. There are also other few things to add. – Frankie_C Jul 04 '20 at 11:07

1 Answers1

2

You must differentiate between shareable objects and static libraries simply because they are really different objects.

A shareable object file, as a DLL or a SO, contains structures used by the loader to allow the dynamic link to and from other executable images (i.e. export tables).

A DLL is at all effects an executable image that, as an executable, can be loaded in memory and relocated (if not position independent code), but not only import symbols, as the executable do, but also expose exported symbols.

Exported symbols can be used by the loader to interlink different executable modules in memory.

A static library, on the other hand, is simply a collection of object modules to be linked in a single executable, or even a DLL.

An object module contains instruction bytecode and placeholder for external symbols which are referenced through the relocation table.

The linker collect object modules one by one each time they are referenced, i.e. a function call, and add the object to the linking code stream, than examine the relocation table of the object module, and replace the occurrence of each external symbol, with a displacement of the symbol inside the linked code. Eventually adding more object modules as new references are discovered. This is a recursive process that will end when no more undefined references remain.

At the end of linking process you have an image of your executable code in the memory. This image will be read and placed in memory by the loader, an OS component, that will fix some minor references and fills the import table with the addresses of symbols imported from DLL's.

Moreover if it is true that you can extract each single object module you need from an archive (library file), you can't extract single parts from a DLL because it is a merge of all modules without any reference for the start and the end of each.

It should be clear now that while an object module, the .obj file, or a collection of them, .lib file, is quite different from a DLL. Raw code the first, a fully linked and 'ready to run' piece of code the second.

The very reason for existence of shareable objects and static libraries is related to efficiency and resource rationalization.

When you statically link library modules you replicate same code for each executable you create using that static library, implying larger executable files that will take longer time to load wasting kernel execution time and memory space.

When you use shareable objects you load the code only the first time, then for all subsequent executables you need only to map the space where the DLL code lays in the new process memory space and create a new data segment (this must be unique for each process to avoid conflicts), effectively optimizing memory and system usage (for lighter loader workload).

So how we have to choose between the two?

Static linking is convenient when your code is used by a limited number of programs, in which case the effort to load a separate DLL module isn't worth.

Static linking also allows to easily reference to process defined global variables or other process local data. This is not possible, or not so easy, with a DLL because being a complete executable can't have undefined references so you must define any global inside the DLL, and this reference will be common for all processes accessing the DLL code.

Dynamic linking is convenient when the code is used by many programs making more efficient the loader work, and reducing the memory usage. Example of this are the system libraries, which are used by almost all programs, or compiler runtime.

HeartWare
  • 7,464
  • 2
  • 26
  • 30
Frankie_C
  • 4,764
  • 1
  • 13
  • 30
  • Thanks for the detailed explanation. Is there any reason that a DLL couldn't be used as a static library? Both libraries contain executable code, correct? In the other direction, would it simply be a matter of adding export table(s) to a static library to make it work as a DLL? Are there any references you could recommend on this topic? – PProteus Jul 06 '20 at 13:10
  • The question is similar to: "Can I link an exe file with another executable?". Of course not because a relocatable object file, an '.obj' file, is not an executable and the reverse. A DLL is exactly an executable, where all object modules have been already linked together and relocation info's has been removed, but instead of having one entry point, the `main`, called from the OS, has many entry point that you can call from your program. A static library is made of an index and many relocatable object modules stuffed in the same file and referenced through the index. – Frankie_C Jul 06 '20 at 13:25
  • @PProteus I added more clarifications to the answer – Frankie_C Jul 06 '20 at 13:44