C How to use dlopen in c?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
dlopen lets a Unix-like program load a shared library at runtime instead of linking it at build time. That is useful for plugin systems, optional features, and tools that need to discover symbols dynamically, but it only works reliably if you handle symbol lookup and error reporting carefully.
The Core Functions
The dynamic loading API usually involves four functions from dlfcn.h:
- '
dlopento load the shared object' - '
dlsymto find a symbol' - '
dlerrorto read loader errors' - '
dlcloseto release the handle'
The usual include is:
On Linux you typically link with -ldl.
Build a Small Shared Library
First create a shared library that exports a function.
Build it:
-fPIC generates position-independent code, and -shared produces a shared object instead of a normal executable.
Load the Library and Call a Function
Now write a program that opens the library and resolves the symbol.
Compile the main program:
If both files are in the current directory, running ./main should print 5.
Why the Function Pointer Cast Matters
dlsym returns void *, so you need to cast it to the correct function-pointer type before calling it. That type must match the real function signature exactly. If the signature is wrong, the call may compile but behave incorrectly at runtime.
This is why defining a typedef such as add_fn is a good habit. It makes the intended signature explicit and easier to review.
RTLD_LAZY Versus RTLD_NOW
The second argument to dlopen controls symbol resolution behavior.
- '
RTLD_NOWresolves symbols immediately' - '
RTLD_LAZYdefers some resolution until the symbol is used'
RTLD_NOW is often easier for debugging because failures happen at load time instead of later during execution.
Use Cases That Actually Justify dlopen
dlopen is useful when:
- plugins should be discovered at runtime
- a dependency is optional
- the program supports extension points without recompilation
- different implementations may be loaded based on configuration
If the dependency is mandatory and fixed, normal linking is usually simpler and safer.
Error Handling Rules
There are two loader rules worth keeping strict:
- Check the return value of
dlopen. - Clear
dlerrorbefore callingdlsym, then check it after.
That second rule matters because dlsym itself does not return errors through an out parameter. The loader keeps the last error message in internal state.
Common Pitfalls
The most common mistake is forgetting -ldl when linking the main executable. On many Linux systems the code compiles but fails at link time without it.
Another issue is using the wrong function-pointer type for a resolved symbol. That can lead to crashes or subtle undefined behavior.
A third problem is assuming the loader will find the library automatically. If the library path is not on the runtime search path, use an absolute path, a relative path such as ./libmathlib.so, or configure the environment correctly.
Summary
- Use
dlopento load shared libraries at runtime on Unix-like systems. - Resolve functions with
dlsymand cast them to the correct function-pointer type. - Check
dlerrorcarefully after symbol lookup. - Link the executable with
-ldlon Linux. - Prefer normal linking unless you actually need runtime loading behavior.

