C++ Dynamic Linking
Master dynamic linking and runtime library loading with interactive visualizations.
Best viewed on desktop for optimal interactive experience
Dynamic Linking at Runtime
Dynamic linking defers library loading until program execution, enabling code sharing and smaller executables.
Dynamic Library Loading
Available Shared Libraries
libc.so.6
v2.31 • 2.1 MB
printfmallocfree+2 more
libm.so.6
v2.31 • 1.5 MB
Depends on: libc.so.6
sincossqrt+2 more
libpthread.so.0
v2.31 • 156 KB
Depends on: libc.so.6
pthread_createpthread_joinpthread_mutex_lock
libstdc++.so.6
v10.2 • 1.9 MB
Depends on: libc.so.6, libm.so.6
std::coutstd::vectorstd::string+1 more
Loading Process
Click "Load" to simulate dynamic loading
Dynamic Linker Environment
LD_LIBRARY_PATH=/custom/lib:/usr/local/lib
LD_PRELOAD=./mylib.so
LD_DEBUG=libs,bindings
Static vs Dynamic
Static Linking
- Code copied into executable
- Larger file size
- No runtime dependencies
- Faster startup
Dynamic Linking
- References to shared libraries
- Smaller executables
- Runtime dependencies
- Memory sharing between processes
Creating Shared Libraries
# Compile with PIC (Position Independent Code) g++ -fPIC -c mylib.cpp # Create shared library g++ -shared -o libmylib.so mylib.o # Link against library g++ main.cpp -L. -lmylib -o program # Run with library path LD_LIBRARY_PATH=. ./program
Runtime Loading with dlopen
#include <dlfcn.h> // Load library at runtime void* handle = dlopen("libplugin.so", RTLD_LAZY); // Get function pointer typedef int (*func_t)(int); func_t func = (func_t)dlsym(handle, "function"); // Call function int result = func(42); // Unload library dlclose(handle);
GOT/PLT Mechanism
Dynamic symbols are resolved through:
- PLT (Procedure Linkage Table): Jump stubs
- GOT (Global Offset Table): Address storage
First call:
- Call goes to PLT stub
- PLT jumps to GOT entry
- GOT points back to resolver
- Resolver finds symbol
- Updates GOT with real address
Subsequent calls go directly through GOT.
Environment Variables
# Library search path LD_LIBRARY_PATH=/custom/lib:$LD_LIBRARY_PATH # Preload libraries LD_PRELOAD=./mylib.so ./program # Debug dynamic linker LD_DEBUG=libs ./program # Force immediate binding LD_BIND_NOW=1 ./program
Troubleshooting
Library Not Found
# Check dependencies ldd program # Find missing library ldconfig -p | grep libname # Add library path export LD_LIBRARY_PATH=/path/to/lib
Symbol Version Issues
# Check symbol versions objdump -T library.so # Force specific version patchelf --replace-needed old.so new.so program
Best Practices
- Version your libraries: Use SONAME
- Minimize dependencies: Reduce complexity
- Use RPATH carefully: Consider security
- Document dependencies: Help users
- Test with ldd: Verify before deployment
Next Steps
- Explore Memory Layout
- Learn about Symbol Resolution
- Understand Program Loading