cdylib_shim/
lib.rs

1/// A macro for creating dynamic library shims that can intercept and modify function calls.
2///
3/// The `shim` macro allows you to create a library that acts as a drop-in replacement for an existing library,
4/// while providing the ability to hook and modify the behavior of exported functions.
5///
6/// # Usage
7///
8/// The macro takes a library name as an argument and is applied to a module. Within this module, you can define:
9///
10/// - An initialization function marked with `#[init]` that runs when the library is loaded
11/// - Hook functions marked with `#[hook]` that intercept calls to specific exported functions
12///
13/// The original library's functions are available through the automatically generated `original` module.
14///
15/// # Example
16///
17/// This example creates a shim for `version.dll` that logs whenever `GetFileVersionInfoA` is called:
18///
19/// ```rust
20/// #![feature(naked_functions)]
21///
22/// use cdylib_shim::shim;
23///
24/// #[shim("version.dll")]
25/// mod version {
26///     use std::{
27///         ffi::{c_char, c_int, c_ulong, c_void},
28///         fs::File,
29///     };
30///
31///     #[init]
32///     fn init() {
33///         let file = File::create("version.log").unwrap();
34///
35///         tracing_subscriber::fmt()
36///             .with_writer(file)
37///             .with_ansi(false)
38///             .init();
39///     }
40///
41///     #[hook]
42///     unsafe extern "system" fn GetFileVersionInfoA(
43///         lptstrFileName: *const c_char,
44///         dwHandle: c_ulong,
45///         dwLen: c_ulong,
46///         lpData: *const c_void,
47///     ) -> c_int {
48///         tracing::info!("Hello from GetFileVersionInfoA!");
49///         unsafe { original::GetFileVersionInfoA(lptstrFileName, dwHandle, dwLen, lpData) }
50///     }
51/// }
52/// ```
53pub use cdylib_shim_macros::shim;
54
55#[doc(hidden)]
56#[path = "private.rs"]
57pub mod __private;