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;