Skip to main content

Crate dlsym

Crate dlsym 

Source
Expand description

Memory-safe bindings around the platform’s dynamic library loading primitives (dlopen/dlsym on Unix, LoadLibraryExW/GetProcAddress on Windows).

The central guarantee of this crate is that a symbol can never outlive the library it was loaded from through safe code:

  • Symbol<'lib, T> borrows its Library, so the borrow checker rejects dropping the library while a symbol is alive.
  • ArcSymbol<T> keeps the library alive through an Arc for when a borrow is impractical (e.g. 'static storage), without resorting to transmute.
  • Neither type hands out the raw function pointer through safe code: functions are invoked through Symbol::call (or Symbol::with for variadic ones), so the pointer cannot be copied out and kept past an unload by accident.
  • The library! macro generates a struct that owns the library together with every resolved symbol, using Rust 2024 unsafe extern block syntax. This is the shape the dlsym-gen tool emits from C headers (see codegen, behind the codegen feature).
use dlsym::Library;

// SAFETY: libm has no unsound initialisers.
let libm = unsafe { Library::open("libm.so.6")? };
// SAFETY: `cos` has this signature in libm.
let cos = unsafe { libm.get::<unsafe extern "C" fn(f64) -> f64>(c"cos")? };
// SAFETY: `cos` is a pure function, valid for any `f64`.
assert_eq!(unsafe { cos.call((0.0,)) }, 1.0);

drop(libm); // fine here; moving this above the call would not compile

§Platform notes

  • Unloading. Borrowing only protects your own use of a library. Some libraries leave threads, thread-local destructors or callbacks behind that crash once they are unloaded; see Libraries that cannot be unloaded.
  • Thread-local data. Looking up a C __thread / _Thread_local variable returns its address for the calling thread. Such a data symbol must only be used on the thread that looked it up.
  • Error reporting. Lookups rely on dlerror to tell a missing symbol from one whose address is null. Its state is thread-local on glibc, musl, Apple platforms and the BSDs, so concurrent lookups from several threads are fine there.
  • Lazy binding. With RTLD_LAZY (see os::unix::OpenOptions), a library whose own dependencies are missing may load fine and abort the process later when a function is first called. Library::open uses RTLD_NOW to report such problems upfront.

Modules§

codegen
Generates library! bindings from C headers.
os
Platform-specific functionality.

Macros§

library
Declares a struct holding a Library and the symbols resolved from it.

Structs§

AddressInfo
What the loader knows about an address: the library containing it and, where available, the nearest exported symbol.
ArcSymbol
A symbol that keeps its Library alive through an Arc.
Library
A loaded dynamic library.
Symbol
A symbol borrowed from a Library.

Enums§

Error
Errors returned when loading libraries or resolving symbols.

Traits§

Bindings
Structs that bundle a Library with symbols resolved from it.
FnPtr
Function pointer types that can be invoked through Symbol::call.
SymbolName
Types that can name a symbol.
SymbolType
Types a symbol address can be interpreted as.

Functions§

library_filename
Returns the platform’s conventional file name for a library called name: lib{name}.so on most Unix systems, lib{name}.dylib on Apple platforms, and {name}.dll on Windows.

Type Aliases§

Result
Convenience alias for results returned by this crate.