### Implement a plugin system Source: https://context7.com/nagisa/rust_libloading/llms.txt Provides a complete example of a plugin architecture where the host application loads shared libraries, initializes them, and invokes functions safely using transmuted symbol lifetimes. ```rust use libloading::{Library, Symbol}; use std::path::Path; // Plugin interface (shared between host and plugins) type PluginInit = unsafe extern "C" fn() -> i32; type PluginProcess = unsafe extern "C" fn(data: *const u8, len: usize) -> i32; type PluginShutdown = unsafe extern "C" fn(); struct Plugin { _lib: Library, // Keep library alive process: Symbol<'static, PluginProcess>, shutdown: Symbol<'static, PluginShutdown>, } impl Plugin { fn load(path: impl AsRef) -> Result> { unsafe { let lib = Library::new(path.as_ref())?; // Initialize plugin let init: Symbol = lib.get(b"plugin_init\0")?; let version = init(); if version != 1 { return Err("Unsupported plugin version".into()); } // Get function pointers with 'static lifetime by transmuting // SAFETY: We keep _lib alive for the lifetime of Plugin let process: Symbol = lib.get(b"plugin_process\0")?; let process = std::mem::transmute::< Symbol<'_, PluginProcess>, Symbol<'static, PluginProcess> >(process); let shutdown: Symbol = lib.get(b"plugin_shutdown\0")?; let shutdown = std::mem::transmute::< Symbol<'_, PluginShutdown>, Symbol<'static, PluginShutdown> >(shutdown); Ok(Plugin { _lib: lib, process, shutdown }) } } fn process(&self, data: &[u8]) -> i32 { unsafe { (self.process)(data.as_ptr(), data.len()) } } } impl Drop for Plugin { fn drop(&mut self) { unsafe { (self.shutdown)(); } } } fn main() -> Result<(), Box> { let plugin = Plugin::load("./plugins/myprocessor.so")?; let result = plugin.process(b"Hello, Plugin!"); println!("Plugin returned: {}", result); Ok(()) } ``` -------------------------------- ### os::unix::Library::open Source: https://context7.com/nagisa/rust_libloading/llms.txt Shows how to open a dynamic library on Unix-like systems with custom flags, allowing control over symbol binding and visibility, and how to get a handle to the current executable. ```APIDOC ## os::unix::Library::open ### Description Open a library with custom flags on Unix systems. Allows specifying `RTLD_LAZY`, `RTLD_NOW`, `RTLD_GLOBAL`, `RTLD_LOCAL`, or platform-specific flags. Pass `None` for filename to get a handle to the current executable. ### Method `Library::open` ### Endpoint `libloading::os::unix::Library::open` ### Parameters #### Path Parameters - `filename` (Option<&str>) - Required - The path to the library file, or `None` for the current executable. - `flags` (i32) - Required - Bitmask of flags like `RTLD_NOW`, `RTLD_GLOBAL`, etc. ### Request Example ```rust use libloading::os::unix::{Library, RTLD_NOW, RTLD_GLOBAL}; unsafe { // Load with eager binding and global symbol visibility let lib = Library::open( Some("/path/to/library.so"), RTLD_NOW | RTLD_GLOBAL )?; // Load symbols from current executable and all loaded libraries let this = Library::this(); let libc_fn: libloading::os::unix::Symbol = this.get(b"printf")?; } ``` ### Response Example (No direct response, returns a `Library` handle on success) ``` -------------------------------- ### os::windows::Library::this Source: https://context7.com/nagisa/rust_libloading/llms.txt Explains how to get a handle to the main program executable on Windows, noting that symbol lookups are restricted to this executable only, unlike the Unix equivalent. ```APIDOC ## os::windows::Library::this ### Description Get a handle to the original program executable on Windows. Note: this behaves differently from `os::unix::Library::this()` - it only represents the main executable, not all loaded modules. ### Method `Library::this` ### Endpoint `libloading::os::windows::Library::this` ### Request Example ```rust use libloading::os::windows::Library; let this = Library::this()?; // Symbol lookups will only search the main executable ``` ### Response Example (Returns a `Library` handle representing the main executable) ``` -------------------------------- ### Install libloading Dependency Source: https://context7.com/nagisa/rust_libloading/llms.txt Add the libloading crate to your project's Cargo.toml file to include it as a dependency. This is the standard method for managing Rust project dependencies. ```toml [dependencies] libloading = "0.9" ``` -------------------------------- ### Access Already Loaded Windows Libraries Source: https://context7.com/nagisa/rust_libloading/llms.txt Attempts to get a handle to a library that is already present in the process address space. This is useful for interacting with existing dependencies without triggering a new load operation. ```rust use libloading::os::windows::Library; fn get_already_loaded() -> Result<(), Box> { match Library::open_already_loaded("user32.dll") { Ok(lib) => { println!("user32.dll is loaded"); unsafe { let func: libloading::os::windows::Symbol i32> = lib.get(b"GetSystemMetrics")?; } } Err(_) => println!("user32.dll is not loaded"), } Ok(()) } ``` -------------------------------- ### Library::get - Get Symbol Pointer Source: https://context7.com/nagisa/rust_libloading/llms.txt Retrieves a pointer to a function or static variable within a loaded library by its symbol name. The symbol name should ideally be null-terminated for efficiency. The caller must specify the correct type for the loaded symbol. ```APIDOC ## Library::get ### Description Get a pointer to a function or static variable by symbol name. The symbol name should not contain null bytes except optionally at the end. Using a null-terminated symbol (e.g., `b"symbol\0"`) avoids an allocation. The caller must specify the correct type for the loaded symbol. ### Method `Library::get(&self, name: &[u8]) -> Result, Error>` ### Endpoint N/A (This is a library function, not an HTTP endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use libloading::{Library, Symbol}; fn call_dynamic_function() -> Result> { unsafe { let lib = Library::new("/path/to/library.so")?; // Load a function - null-terminated for efficiency let func: Symbol u32> = lib.get(b"my_function\0")?; let result = func(42); // Load a function without null terminator (allocates) let func2: Symbol f64> = lib.get(b"compute")?; let result2 = func2(3.14); // Load a static variable let var: Symbol<*mut u32> = lib.get(b"GLOBAL_COUNTER\0")?; **var = 100; Ok(result) } } ``` ### Response #### Success Response (200) `Symbol` object representing the loaded symbol, where `T` is the specified type. #### Response Example N/A (Rust function return type) ``` -------------------------------- ### Library::new - Load a Dynamic Library Source: https://context7.com/nagisa/rust_libloading/llms.txt Demonstrates how to load a dynamic library using `Library::new`. It supports loading by absolute path, library name (searches standard paths), or relative path. Loading is an unsafe operation. ```APIDOC ## Library::new ### Description Find and load a dynamic library from a filename or path. The filename can be a library name, absolute path, or relative path. On Unix, this uses `dlopen` with `RTLD_LAZY | RTLD_LOCAL` flags. On Windows, this uses `LoadLibraryExW`. Loading is unsafe because library initialization routines are executed during the load. ### Method `Library::new(path: &str) -> Result` ### Endpoint N/A (This is a library function, not an HTTP endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use libloading::Library; fn load_library() -> Result<(), Box> { unsafe { // Load by absolute path let lib = Library::new("/usr/lib/libssl.so")?; // Load by library name (platform searches standard paths) let lib = Library::new("libssl.so.3")?; // Load by relative path let lib = Library::new("./plugins/myplugin.so")?; } Ok(()) } ``` ### Response #### Success Response (200) `Library` object representing the loaded dynamic library. #### Response Example N/A (Rust function return type) ``` -------------------------------- ### Load Dynamic Library with Library::new Source: https://context7.com/nagisa/rust_libloading/llms.txt Demonstrates how to load a dynamic library using the `Library::new` function. This function supports loading by absolute path, library name (using platform-specific search paths), or relative path. Loading is an unsafe operation as it executes library initialization routines. ```rust use libloading::Library; fn load_library() -> Result<(), Box> { unsafe { // Load by absolute path let lib = Library::new("/usr/lib/libssl.so")?; // Load by library name (platform searches standard paths) let lib = Library::new("libssl.so.3")?; // Load by relative path let lib = Library::new("./plugins/myplugin.so")?; } Ok(()) } ``` -------------------------------- ### Load Unix Libraries with Custom Flags Source: https://context7.com/nagisa/rust_libloading/llms.txt Shows how to open dynamic libraries on Unix systems using specific flags like RTLD_NOW and RTLD_GLOBAL. It also demonstrates accessing symbols from the current executable using Library::this(). ```rust use libloading::os::unix::{Library, RTLD_NOW, RTLD_GLOBAL}; fn unix_custom_flags() -> Result<(), Box> { unsafe { let lib = Library::open( Some("/path/to/library.so"), RTLD_NOW | RTLD_GLOBAL )?; let this = Library::this(); let libc_fn: libloading::os::unix::Symbol = this.get(b"printf")?; } Ok(()) } ``` -------------------------------- ### os::windows::Library::load_with_flags Source: https://context7.com/nagisa/rust_libloading/llms.txt Illustrates loading libraries on Windows with custom flags to control search paths, security settings, and loading modes, such as loading only from System32 or as a data file. ```APIDOC ## os::windows::Library::load_with_flags ### Description Load a library on Windows with custom flags for controlling search behavior, security, and loading mode. ### Method `Library::load_with_flags` ### Endpoint `libloading::os::windows::Library::load_with_flags` ### Parameters #### Path Parameters - `filename` (str) - Required - The name of the library file. - `flags` (u32) - Required - Bitmask of flags like `LOAD_LIBRARY_SEARCH_SYSTEM32`, `LOAD_LIBRARY_AS_DATAFILE`, etc. ### Request Example ```rust use libloading::os::windows::{ Library, LOAD_LIBRARY_SEARCH_SYSTEM32, LOAD_LIBRARY_AS_DATAFILE, }; unsafe { // Load only from System32 directory let lib = Library::load_with_flags( "kernel32.dll", LOAD_LIBRARY_SEARCH_SYSTEM32 )?; // Load as data file (for resource extraction, no code execution) let resource_lib = Library::load_with_flags( "myresources.dll", LOAD_LIBRARY_AS_DATAFILE )?; } ``` ### Response Example (Returns a `Library` handle on success) ``` -------------------------------- ### Load Windows Libraries with Custom Flags Source: https://context7.com/nagisa/rust_libloading/llms.txt Demonstrates loading Windows DLLs with specific security and search flags, such as restricting loading to the System32 directory or loading as a data file. ```rust use libloading::os::windows::{ Library, LOAD_LIBRARY_SEARCH_SYSTEM32, LOAD_LIBRARY_AS_DATAFILE, }; fn windows_custom_flags() -> Result<(), Box> { unsafe { let lib = Library::load_with_flags( "kernel32.dll", LOAD_LIBRARY_SEARCH_SYSTEM32 )?; let resource_lib = Library::load_with_flags( "myresources.dll", LOAD_LIBRARY_AS_DATAFILE )?; } Ok(()) } ``` -------------------------------- ### os::windows::Library::open_already_loaded Source: https://context7.com/nagisa/rust_libloading/llms.txt Demonstrates how to obtain a handle to a library that is already loaded in the process on Windows, returning an error if the library is not found. Useful for accessing libraries loaded by other components. ```APIDOC ## os::windows::Library::open_already_loaded ### Description Get a handle to a library that is already loaded in the process. Returns an error if the library is not currently loaded. Useful for accessing libraries loaded by other components. ### Method `Library::open_already_loaded` ### Endpoint `libloading::os::windows::Library::open_already_loaded` ### Parameters #### Path Parameters - `name` (str) - Required - The name of the library to check for. ### Request Example ```rust use libloading::os::windows::Library; // Check if library is loaded, don't load it if not match Library::open_already_loaded("user32.dll") { Ok(lib) => { println!("user32.dll is loaded"); unsafe { let func: libloading::os::windows::Symbol i32> = lib.get(b"GetSystemMetrics")?; } } Err(_) => println!("user32.dll is not loaded"), } ``` ### Response Example (Returns a `Library` handle if the library is loaded, otherwise an error) ``` -------------------------------- ### os::unix::Library::this Source: https://context7.com/nagisa/rust_libloading/llms.txt Provides a way to obtain a handle to the current executable on Unix systems, enabling symbol lookups within the main program and all loaded libraries. ```APIDOC ## os::unix::Library::this ### Description Get a handle to the current executable on Unix. Symbol lookups search the original program, libraries loaded at startup, and libraries loaded at runtime. ### Method `Library::this` ### Endpoint `libloading::os::unix::Library::this` ### Request Example ```rust use libloading::os::unix::Library; // Get handle to current process let this = Library::this(); unsafe { // Search for a symbol in any loaded library let func: libloading::os::unix::Symbol i32> = this.get(b"getpid")?; let pid = func(); println!("PID: {}", pid); } ``` ### Response Example (Returns a `Library` handle representing the current executable) ``` -------------------------------- ### Manage Symbol Handles with into_raw and from_raw Source: https://context7.com/nagisa/rust_libloading/llms.txt Demonstrates how to extract a raw symbol handle from a library and re-wrap it to restore lifetime safety. This is useful for low-level interoperability where the library reference must be manually managed. ```rust use libloading::{Library, Symbol}; fn raw_symbol_handling() -> Result<(), Box> { unsafe { let lib = Library::new("/path/to/library.so")?; let symbol: Symbol<*mut u32> = lib.get(b"my_var\0")?; let raw = symbol.into_raw(); let symbol_again = Symbol::from_raw(raw, &lib); } Ok(()) } ``` -------------------------------- ### Symbol::into_raw / Symbol::from_raw Source: https://context7.com/nagisa/rust_libloading/llms.txt Demonstrates how to extract a raw symbol handle from a `Symbol` object, relinquishing lifetime guarantees, and how to re-wrap it with a library reference to restore lifetime safety. ```APIDOC ## Symbol::into_raw / Symbol::from_raw ### Description Extract or wrap the platform-specific symbol handle. `into_raw` relinquishes lifetime guarantees. `from_raw` requires a library reference to re-establish the lifetime connection. ### Method `Symbol::into_raw`, `Symbol::from_raw` ### Parameters - `raw` (*): The raw symbol handle obtained from `into_raw`. - `lib` (*): A reference to the `Library` object to re-establish lifetime connection. ### Request Example ```rust use libloading::{Library, Symbol}; unsafe { let lib = Library::new("/path/to/library.so")?; let symbol: Symbol<*mut u32> = lib.get(b"my_var\0")?; // Extract raw platform-specific symbol (loses lifetime safety) let raw = symbol.into_raw(); // Re-wrap with library reference (restores lifetime safety) let symbol_again = Symbol::from_raw(raw, &lib); } ``` ### Response Example (No direct response, operations modify symbol handling) ``` -------------------------------- ### Handle dynamic loading errors Source: https://context7.com/nagisa/rust_libloading/llms.txt Illustrates how to match against the Error enum to handle specific failure scenarios like dlopen failures on Unix or LoadLibraryExW failures on Windows. ```rust use libloading::{Library, Error}; fn handle_errors() { unsafe { match Library::new("nonexistent.so") { Ok(lib) => println!("Loaded successfully"), Err(Error::DlOpen { source }) => { println!("Unix dlopen failed: {}", source); } Err(Error::DlOpenUnknown) => { println!("Unix dlopen failed without error message"); } Err(Error::LoadLibraryExW { source }) => { println!("Windows LoadLibraryExW failed: {}", source); } Err(Error::IncompatibleSize) => { println!("Requested type size doesn't match pointer size"); } Err(Error::InteriorZeroElements) => { println!("Filename or symbol contains interior null bytes"); } Err(e) => println!("Other error: {}", e), } } } ``` -------------------------------- ### Load symbols by ordinal on Windows Source: https://context7.com/nagisa/rust_libloading/llms.txt Demonstrates how to retrieve functions or variables from a DLL using their ordinal number instead of a string name. This is useful for legacy Windows DLLs that do not export symbols by name. ```rust use libloading::os::windows::Library; fn get_by_ordinal() -> Result<(), Box> { unsafe { let lib = Library::new("mylib.dll")?; // Get function exported as ordinal #1 let func: libloading::os::windows::Symbol i32> = lib.get_ordinal(1)?; let result = func(); } Ok(()) } ``` -------------------------------- ### library_filename - Platform-Appropriate Filename Source: https://context7.com/nagisa/rust_libloading/llms.txt Converts a base library name into the platform-specific filename, automatically adding the correct prefix (e.g., `lib` on Unix) and suffix (e.g., `.so`, `.dylib`, `.dll`). ```APIDOC ## library_filename ### Description Convert a library name to the platform-appropriate filename. Adds the correct prefix (`lib` on Unix) and suffix (`.so`, `.dylib`, `.dll`) for the target platform. ### Method `library_filename(name: &str) -> String` ### Endpoint N/A (This is a library function, not an HTTP endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use libloading::{Library, library_filename}; fn load_cross_platform() -> Result<(), Box> { // Creates "libLLVM.so" on Linux, "libLLVM.dylib" on macOS, "LLVM.dll" on Windows let filename = library_filename("LLVM"); unsafe { let lib = Library::new(filename)?; } Ok(()) } ``` ### Response #### Success Response (200) A `String` containing the platform-specific library filename. #### Response Example `"libLLVM.so"` (on Linux) `"libLLVM.dylib"` (on macOS) `"LLVM.dll"` (on Windows) ``` -------------------------------- ### Pin libraries in memory on Windows Source: https://context7.com/nagisa/rust_libloading/llms.txt Shows how to pin a library in memory, ensuring it remains loaded even after the Library object is dropped. This is critical when raw pointers to the library's memory are held by other parts of the application. ```rust use libloading::os::windows::Library; fn pin_library() -> Result<(), Box> { unsafe { let lib = Library::new("important.dll")?; // Pin the library - it will never be unloaded lib.pin()?; // Library stays loaded even after lib is dropped } Ok(()) } ``` -------------------------------- ### Retrieve Function Pointers and Variables with Library::get Source: https://context7.com/nagisa/rust_libloading/llms.txt Shows how to obtain pointers to functions or static variables from a loaded dynamic library using `Library::get`. It covers using null-terminated symbol names for efficiency and handling symbols without null terminators, which involve an allocation. The caller must ensure the correct type is specified for the retrieved symbol. ```rust use libloading::{Library, Symbol}; fn call_dynamic_function() -> Result> { unsafe { let lib = Library::new("/path/to/library.so")?; // Load a function - null-terminated for efficiency let func: Symbol u32> = lib.get(b"my_function\0")?; let result = func(42); // Load a function without null terminator (allocates) let func2: Symbol f64> = lib.get(b"compute")?; let result2 = func2(3.14); // Load a static variable let var: Symbol<*mut u32> = lib.get(b"GLOBAL_COUNTER\0")?; **var = 100; Ok(result) } } ``` -------------------------------- ### Cross-Platform Library Filename with library_filename Source: https://context7.com/nagisa/rust_libloading/llms.txt Uses the `library_filename` function to generate the platform-appropriate filename for a dynamic library. This function automatically adds the correct prefix (e.g., 'lib' on Unix) and suffix (e.g., '.so', '.dylib', '.dll') based on the target operating system. ```rust use libloading::{Library, library_filename}; fn load_cross_platform() -> Result<(), Box> { // Creates "libLLVM.so" on Linux, "libLLVM.dylib" on macOS, "LLVM.dll" on Windows let filename = library_filename("LLVM"); unsafe { let lib = Library::new(filename)?; } Ok(()) } ``` -------------------------------- ### Search Symbols in Current Unix Process Source: https://context7.com/nagisa/rust_libloading/llms.txt Retrieves a handle to the current process on Unix, allowing for the lookup of symbols across the main executable and all currently loaded libraries. ```rust use libloading::os::unix::Library; fn search_loaded_symbols() -> Result<(), Box> { let this = Library::this(); unsafe { let func: libloading::os::unix::Symbol i32> = this.get(b"getpid")?; let pid = func(); println!("PID: {}", pid); } Ok(()) } ``` -------------------------------- ### Handle Optional Symbols with Symbol::lift_option Source: https://context7.com/nagisa/rust_libloading/llms.txt Demonstrates how to safely extract an `Option` from a `Symbol` using `Symbol::lift_option`. This is particularly useful when dealing with symbols that might legitimately be null. It converts a `Symbol>` into an `Option>`. ```rust use libloading::{Library, Symbol}; fn get_optional_symbol() -> Result<(), Box> { unsafe { let lib = Library::new("/path/to/library.so")?; // Get symbol that might be null let maybe_ptr: Symbol> = lib.get(b"optional_var\0")?; // Convert to Option> if let Some(ptr) = maybe_ptr.lift_option() { println!("Found symbol at {:?}", *ptr); } else { println!("Symbol is null"); } } Ok(()) } ``` -------------------------------- ### os::unix::Library::get_singlethreaded Source: https://context7.com/nagisa/rust_libloading/llms.txt Explains the use of `get_singlethreaded` on Unix platforms where `dlerror` might not be thread-safe, allowing symbol lookups while avoiding potential issues in concurrent environments. ```APIDOC ## os::unix::Library::get_singlethreaded ### Description Get a symbol on Unix platforms where `dlerror` is not MT-safe. Unlike `get()`, this method can return null pointers without error on platforms with MT-safe dlerror. Use only when thread safety is guaranteed by the caller. ### Method `Library::get_singlethreaded` ### Endpoint `libloading::os::unix::Library::get_singlethreaded` ### Parameters #### Path Parameters - `name` (*): The name of the symbol to retrieve (as a byte slice). ### Request Example ```rust use libloading::os::unix::Library; unsafe { let lib = Library::new("/path/to/library.so")?; // Safe to use when no concurrent dlerror calls occur let func: libloading::os::unix::Symbol i32> = lib.get_singlethreaded(b"my_function\0")?; } ``` ### Response Example (Returns a `Symbol` handle or potentially null on specific platforms) ``` -------------------------------- ### Symbol::lift_option - Handle Optional Symbols Source: https://context7.com/nagisa/rust_libloading/llms.txt Lifts an `Option` out of a `Symbol`, converting `Symbol>` to `Option>`. This is useful when dealing with symbols that might legitimately be null. ```APIDOC ## Symbol::lift_option ### Description Lift an Option out of a Symbol, useful when a symbol might legitimately be null. This converts `Symbol>` to `Option>`. ### Method `Symbol::lift_option(self) -> Option>` ### Endpoint N/A (This is a library function, not an HTTP endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use libloading::{Library, Symbol}; fn get_optional_symbol() -> Result<(), Box> { unsafe { let lib = Library::new("/path/to/library.so")?; // Get symbol that might be null let maybe_ptr: Symbol> = lib.get(b"optional_var\0")?; // Convert to Option> if let Some(ptr) = maybe_ptr.lift_option() { println!("Found symbol at {:?}", *ptr); } else { println!("Symbol is null"); } } Ok(()) } ``` ### Response #### Success Response (200) An `Option>`. `Some(Symbol)` if the original symbol contained a value, `None` otherwise. #### Response Example N/A (Rust function return type) ``` -------------------------------- ### Explicitly Unload Library with Library::close Source: https://context7.com/nagisa/rust_libloading/llms.txt Illustrates the use of `Library::close` for explicitly unloading a dynamic library and handling potential errors during the unload process. If `close` is not called, the library is automatically unloaded when the `Library` object is dropped, but any errors during automatic unloading are ignored. ```rust use libloading::Library; fn load_and_close() -> Result<(), libloading::Error> { unsafe { let lib = Library::new("/path/to/library.so")?; // Use the library... // Explicitly close and handle potential errors lib.close()?; } Ok(()) } ``` -------------------------------- ### Perform Single-Threaded Symbol Lookup on Unix Source: https://context7.com/nagisa/rust_libloading/llms.txt Uses get_singlethreaded for environments where dlerror is not thread-safe. This method should only be used when the caller can guarantee no concurrent library access occurs. ```rust use libloading::os::unix::Library; fn singlethreaded_lookup() -> Result<(), Box> { unsafe { let lib = Library::new("/path/to/library.so")?; let func: libloading::os::unix::Symbol i32> = lib.get_singlethreaded(b"my_function\0")?; } Ok(()) } ``` -------------------------------- ### Library::close - Explicitly Unload Library Source: https://context7.com/nagisa/rust_libloading/llms.txt Allows for explicit unloading of a dynamic library and handling any potential errors during the unload process. If not called, the library is automatically unloaded when the `Library` object is dropped, but errors are ignored in that case. This method consumes the `Library` object. ```APIDOC ## Library::close ### Description Explicitly unload the library and handle any errors. If not called, the library is automatically unloaded when dropped, but errors are ignored. This method consumes the library. ### Method `Library::close(self) -> Result<(), Error>` ### Endpoint N/A (This is a library function, not an HTTP endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use libloading::Library; fn load_and_close() -> Result<(), libloading::Error> { unsafe { let lib = Library::new("/path/to/library.so")?; // Use the library... // Explicitly close and handle potential errors lib.close()?; } Ok(()) } ``` ### Response #### Success Response (200) `Ok(())` if the library was unloaded successfully. #### Response Example N/A (Rust function return type) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.