Posted Joe Chu 6 minutes read (About 878 words)0 visits
Load Functions from Shared Libraries
Loading the partial shared library can be beneficial for two reasons:
Original shared library can be very large sometimes(100+ Mb).
Original shared library is not accessible until runtime(OEM specific libraries such OpenCL).
1. Demo
We will start with a customized demo example to illustrate how to load partial shared library at runtime.
We will generate a simplified math library containing basic algorithmic operations(add, subtract, multiply and divide). test.cpp will load these functions at runtime.
If you’re using a Mac with Apple silicon, you can follow my tutorial step by step to reproduce the results. For other operating systems, like Linux or Windows, the process is generally similar, but you may need to do some research and make a few adjustments.
To install jpeg library:
1
brew install libjpeg
You should be able to see the installed location in your terminal message. For example, mine is:
1 2 3 4 5 6
If you need to have jpeg first in your PATH, run: echo 'export PATH="/opt/homebrew/opt/jpeg/bin:$PATH"' >> ~/.zshrc
For compilers to find jpeg you may need to set: export LDFLAGS="-L/opt/homebrew/opt/jpeg/lib" export CPPFLAGS="-I/opt/homebrew/opt/jpeg/include"
Let’s write a C++ program to read a jpeg format image. In our program, we only load needed functions to read an image.
// Function pointer types using modern C++ syntax using jpeg_std_error_type = struct jpeg_error_mgr* (*)(struct jpeg_error_mgr* err); using jpeg_CreateDecompress_type = void (*)(j_decompress_ptr cinfo, int version, size_t structsize); using jpeg_destroy_decompress_type = void (*)(j_decompress_ptr cinfo); using jpeg_read_header_type = int (*)(j_decompress_ptr cinfo, boolean require_image); using jpeg_start_decompress_type = boolean (*)(j_decompress_ptr cinfo); using jpeg_abort_decompress_type = void (*)(j_decompress_ptr cinfo); using jpeg_stdio_src_type = void (*)(j_decompress_ptr cinfo, FILE* infile);
// Open the shared library void* handle = dlopen("/opt/homebrew/opt/jpeg/lib/libjpeg.dylib", RTLD_LAZY); if (!handle) { // Try an alternative path if the first one fails handle = dlopen("./libjpeg.dylib", RTLD_LAZY); if (!handle) { std::cerr << "Cannot open library: " << dlerror() << std::endl; return1; } }
// Load the functions auto jpeg_std_error = reinterpret_cast<jpeg_std_error_type>(dlsym(handle, "jpeg_std_error")); auto jpeg_CreateDecompress = reinterpret_cast<jpeg_CreateDecompress_type>(dlsym(handle, "jpeg_CreateDecompress")); auto jpeg_destroy_decompress = reinterpret_cast<jpeg_destroy_decompress_type>(dlsym(handle, "jpeg_destroy_decompress")); auto jpeg_read_header = reinterpret_cast<jpeg_read_header_type>(dlsym(handle, "jpeg_read_header")); auto jpeg_start_decompress = reinterpret_cast<jpeg_start_decompress_type>(dlsym(handle, "jpeg_start_decompress")); auto jpeg_abort_decompress = reinterpret_cast<jpeg_abort_decompress_type>(dlsym(handle, "jpeg_abort_decompress")); auto jpeg_stdio_src = reinterpret_cast<jpeg_stdio_src_type>(dlsym(handle, "jpeg_stdio_src"));