DLL, explained
What a Dynamic Link Library is, why it exists, and what it actually does.
What it is
A DLL — Dynamic Link Library — is a file on Windows that
contains code and data that other programs can use. It's not a program you
run by double-clicking. It's a library of functions that an .exe (or
another DLL) loads and calls while it runs.
DLLs typically end in .dll, but the same concept goes by other names on
other systems: .so (shared object) on Linux, .dylib on
macOS.
Analogy: Think of an .exe as a chef and a DLL as a
shared pantry. Instead of every chef growing their own vegetables, they all reach
into the same pantry for what they need. The pantry is the DLL — one copy, used by
many.
Why it exists
Three main reasons:
- Reuse. The code that draws a window or encrypts a password doesn't need to be copied into every program. It lives in one DLL and everyone shares it.
-
Smaller programs. If ten apps all use
kernel32.dll, the code for common tasks only exists once on disk and once in memory. - Updates without recompiling. Patch the DLL and every program using it picks up the change — no need to rebuild or redistribute those programs.
How it works
At a high level:
- You launch an
.exe. - Windows' loader reads the executable and sees a list of DLLs it needs (the import table).
- For each DLL, the loader finds the file, maps it into the process's memory, and wires up the function calls.
- The program runs, calling functions that actually live inside those DLLs.
Two ways a DLL can be loaded:
Load-time (implicit)
The program names the DLL up front. If the DLL is missing, the program won't start at all — you'll get the classic "The program can't start because X.dll is missing."
Run-time (explicit)
The program calls LoadLibrary() when it actually needs the DLL, then
looks up functions with GetProcAddress(). Useful for optional
features — the program runs fine without the DLL, just without that feature.
DLL vs. static library
A static library is baked into the executable at build time. A dynamic library (DLL) is loaded at run time.
Static: myapp.exe = [app code] + [library code copied in]
Dynamic: myapp.exe = [app code] → library.dll (loaded later)
Trade-off: static libraries are self-contained and simpler to ship, but bigger and harder to update. DLLs are smaller and updatable, but add a dependency the program must find at run time.
Common problems
"DLL not found"
The loader couldn't find a required DLL. Causes include: it was deleted, the wrong
version is installed, or it's not on the search path. Windows searches — in order —
the app's folder, system folders, then PATH.
DLL hell
When two programs need different versions of the same DLL and installing one breaks the other. Modern Windows mitigates this with Side-by-Side (SxS) assemblies and per-app folders, but it still occasionally bites.
Bitness mismatch
A 64-bit program can't load a 32-bit DLL, or vice versa. Both must match.
Are DLLs safe?
A DLL is just code — as safe or as dangerous as any other program. Because Windows trusts DLLs placed next to an executable, attackers have historically abused this:
- DLL hijacking / preloading: tricking a program into loading a malicious DLL from a location the attacker controls.
-
Malicious DLLs: a
.dllfrom an untrusted source can run arbitrary code once loaded.
Practical rules: only load DLLs you trust, keep software updated, and don't drop random DLLs into a program's folder hoping to "fix" something.