dynamic/shared library (.so file)

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, using dlopendlsym, and dlclose.  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:

  1. 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.

  2. Runtime: When you run the executable (myapp), the dynamic linker/loader (ld.so or ld-linux.so) loads the shared library into memory. This happens before the main function of your program is executed. The dynamic linker uses the LD_LIBRARY_PATH environment variable (or other mechanisms like rpath or ldconfig 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 dlopendlsym, and dlclose functions provided by the dlfcn.h library in Unix-like systems. This approach is known as dynamic loading.

Example

  1. 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
  2. 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;
    }

  3. 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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值