il2cpp_bridge_rs/lib.rs
1#![allow(clippy::missing_safety_doc)]
2#![allow(clippy::not_unsafe_ptr_arg_deref)]
3
4//! Runtime-first IL2CPP integration for Rust.
5//!
6//! `il2cpp-bridge-rs` is designed for code already running inside a process that
7//! has Unity's IL2CPP runtime loaded. It resolves IL2CPP exports at runtime,
8//! builds a metadata cache, and exposes higher-level wrappers for common tasks
9//! such as:
10//!
11//! - locating assemblies and classes
12//! - selecting and invoking methods
13//! - reading fields and properties
14//! - finding Unity objects in the scene
15//! - dumping metadata into C#-like pseudo-code
16//!
17//! The crate does not hide the fact that IL2CPP integration is pointer-heavy and
18//! runtime-sensitive. It aims to make the common paths easier and harder to
19//! misuse, not to turn IL2CPP into a purely safe abstraction.
20//!
21//! # Recommended Flow
22//!
23//! 1. Call [`init`] once the target process has loaded IL2CPP.
24//! 2. Use [`api::cache`] helpers to reach assemblies.
25//! 3. Resolve [`structs::Class`] and [`structs::Method`] values from the cache.
26//! 4. Prefer instance-bound lookups such as [`structs::Object::method`] for
27//! instance calls.
28//! 5. Attach additional threads with [`api::Thread`] before doing runtime work
29//! outside the initialization callback.
30//!
31//! # Example
32//!
33//! ```no_run
34//! use il2cpp_bridge_rs::{api, init};
35//! use std::ffi::c_void;
36//!
37//! init("GameAssembly", || {
38//! let asm = api::cache::csharp();
39//! let player = asm
40//! .class("PlayerController")
41//! .expect("PlayerController should exist");
42//!
43//! let method = player
44//! .method(("TakeDamage", ["System.Single"]))
45//! .expect("TakeDamage(float) should exist");
46//!
47//! println!("Resolved {}::{} @ RVA 0x{:X}", player.name, method.name, method.rva);
48//!
49//! if let Some(obj) = player.find_objects_of_type(false).into_iter().next() {
50//! let bound = obj
51//! .method(("TakeDamage", ["System.Single"]))
52//! .expect("instance method should exist");
53//!
54//! let amount: f32 = 25.0;
55//! unsafe {
56//! let _: Result<(), _> =
57//! bound.call(&[&amount as *const f32 as *mut c_void]);
58//! }
59//! }
60//! });
61//! ```
62//!
63//! This example is `no_run` because it depends on a live Unity IL2CPP runtime.
64//! In normal usage, generated rustdoc should be treated as the canonical
65//! signature-level reference, while the repository markdown guides explain
66//! workflows and platform/runtime caveats.
67
68pub mod api;
69mod init;
70pub mod logger;
71pub mod memory;
72pub mod structs;
73
74pub use init::init;