conclusion & compare:
- Static Linking: The library code is included in the executable at compile time. No separate loading at runtime. e.g. linux : .a , windows: .lib
- Dynamic Linking: The executable is linked with references to shared libraries at compile time. The shared library is loaded automatically by the dynamic linker when the executable is run, before the
main()
function is executed. e.g. linux : .so , windows: .dll - Dynamic Loading: The executable is linked with the
libdl
library, The shared libraries are loaded manually at runtime, at any point in the program, usingdlopen
,dlsym
, anddlclose
. e.g. linux : .so , windows: .dll
For dynamic/shared library (.so file)
1) . dynamic link
To use a dynamic/shared library (.so file) in a C++ project, you need to follow these steps:
Create the Shared Library:
1.Write your library code.
2.Compile the code into a shared library.
3.Link the Shared Library:
Link your application with the shared library during the compilation.
Set the Library Path: Ensure the runtime linker can find your shared library.
Step-by-Step Example
1. Create the Shared Library
Suppose you have a simple library with a function in mylib.cpp:
// mylib.cpp
#include <iostream>
void hello() {
std::cout << "Hello, World!" << std::endl;
}
Compile this into a shared library:
g++ -fPIC -shared -o libmylib.so mylib.cpp
2. Link the Shared Library
Create an application that uses this library in main.cpp
:
// main.cpp
extern void hello();
int main() {
hello();
return 0;
}
Compile the application and link it with the shared library:
g++ -o myapp main.cpp -L. -lmylib
Here, -L.
tells the linker to look in the current directory for libraries, and -lmylib
tells it to link with libmylib.so
.
3. Set the Library Path
Before running the application, set the LD_LIBRARY_PATH
to include the directory where libmylib.so
is located:
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
Now you can run your application:
./myapp
The shared library libmylib.so
is loaded at runtime, not at the linking period. Here's a detailed explanation:
-
Linking Period: During the linking period, the linker (
ld
) does not include the shared library code in the executable. Instead, it includes references to the shared library. This is why the executable is smaller and why you need the shared library available at runtime. -
Runtime: When you run the executable (
myapp
), the dynamic linker/loader (ld.so
orld-linux.so
) loads the shared library into memory. This happens before themain
function of your program is executed. The dynamic linker uses theLD_LIBRARY_PATH
environment variable (or other mechanisms likerpath
orldconfig
cache) to locate the shared library.
Summary
- Linking Period: The executable is linked with references to the shared library.
- Runtime: The shared library is loaded into memory when the executable is run.
This allows for the shared library to be updated independently of the executable, as long as the interface (e.g., function signatures) remains consistent.
2) dynamic loading
load a shared library (.so
file) manually in your code using the dlopen
, dlsym
, and dlclose
functions provided by the dlfcn.h
library in Unix-like systems. This approach is known as dynamic loading.
Example
-
Create the Shared Library:
// mylib.cpp #include <iostream> extern "C" void hello() { std::cout << "Hello, World!" << std::endl; }
Compile this into a shared library:
g++ -fPIC -shared -o libmylib.so mylib.cpp
-
Load the Shared Library Manually:
// main.cpp #include <iostream> #include <dlfcn.h> typedef void (*hello_t)(); int main() { // Load the shared library void* handle = dlopen("./libmylib.so", RTLD_LAZY); if (!handle) { std::cerr << "Cannot open library: " << dlerror() << std::endl; return 1; } // Load the symbol dlerror(); // Reset errors hello_t hello = (hello_t) dlsym(handle, "hello"); const char* dlsym_error = dlerror(); if (dlsym_error) { std::cerr << "Cannot load symbol 'hello': " << dlsym_error << std::endl; dlclose(handle); return 1; } // Use the symbol hello(); // Close the library dlclose(handle); return 0; }
-
Compile and Run the Application:
g++ -o myapp main.cpp -ldl export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./myapp
The -ldl option in the g++ command is used to link the program with the libdl library. This library provides functions for dynamic loading of shared libraries at runtime, such as dlopen, dlsym, dlclose, and dlerror.
Explanation of libdl Functions
dlopen: Opens a shared library and returns a handle to it.
dlsym: Retrieves the address of a symbol (function or variable) from the shared library.
dlclose: Closes the shared library.
dlerror: Returns a string describing the last error that occurred during dynamic linking.