pub use cleat_macros::*;
use il2cpp_bridge_rs as bridge;
use std::ffi::{CString, c_void};
mod class;
mod error;
mod init;
mod math;
mod method;
mod object;
mod types;
mod value_type;
#[cfg(target_os = "android")]
mod hook;
pub mod prelude;
pub use class::Il2CppClass;
pub use error::{Error, Result};
pub use init::{app_data, init, set_app_data};
pub use math::{Quaternion, Vector2, Vector3, Vector4};
pub use method::MethodInfo;
pub use object::Il2CppObject;
pub use types::{Il2CppArray, Il2CppList, Il2CppString};
pub use value_type::{Args, Il2CppValueType};
pub fn resolve_icall(name: &str) -> Result<*mut std::ffi::c_void> {
let c_name =
CString::new(name).map_err(|_| Error::Bridge("iCall name contains null byte".into()))?;
let ptr = unsafe { bridge::api::resolve_icall(c_name.as_ptr()) };
if ptr.is_null() {
return Err(Error::Bridge(format!("iCall not found: {name}")));
}
Ok(ptr)
}
macro_rules! icall_arity {
(0, $name:ident,) => {
pub unsafe fn $name(fn_ptr: *mut c_void) -> *mut c_void {
let f: extern "C" fn() -> *mut c_void = unsafe { std::mem::transmute(fn_ptr) };
f()
}
};
}
macro_rules! icall_arity_n {
($name:ident, $($pn:ident : $pt:ty),+) => {
pub unsafe fn $name(fn_ptr: *mut c_void, $($pn: $pt),+) -> *mut c_void {
let f: extern "C" fn($($pt),+) -> *mut c_void =
unsafe { std::mem::transmute(fn_ptr) };
f($($pn),+)
}
};
}
icall_arity!(0, invoke_icall_0,);
icall_arity_n!(invoke_icall_1, a: *mut c_void);
icall_arity_n!(invoke_icall_2, a: *mut c_void, b: *mut c_void);
icall_arity_n!(invoke_icall_3, a: *mut c_void, b: *mut c_void, c: *mut c_void);
#[cfg(target_os = "android")]
pub use hook::HookGuard;
#[cfg(not(target_os = "android"))]
pub struct HookGuard;
#[cfg(not(target_os = "android"))]
impl HookGuard {
pub fn install(
_target: *const std::ffi::c_void,
_replace: *const std::ffi::c_void,
) -> crate::Result<Self> {
log::warn!("HookGuard::install called on non-Android platform — skipping");
Ok(Self)
}
pub fn trampoline(&self) -> *const std::ffi::c_void {
std::ptr::null()
}
pub fn uninstall(self) -> crate::Result<()> {
Ok(())
}
}
#[cfg(not(target_os = "android"))]
unsafe impl Send for HookGuard {}
#[cfg(not(target_os = "android"))]
unsafe impl Sync for HookGuard {}