Skip to main content

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;