#[relocate]
Expand description
Relocates an address using Skyrim runtime-specific relocation IDs.
The #[relocate]
attribute macro enables dynamic resolution of a pointer using relocation
IDs for Skyrim Special Edition (SE), Anniversary Edition (AE), and optionally VR. It injects code
to resolve the address at runtime and execute user-provided logic through a closure, passing the
resolved pointer as an argument.
§Attributes
Attribute | Type | Required | Description |
---|---|---|---|
cast_as | &str | Yes | The type to cast the resolved pointer to (e.g., "*mut bool" , "*mut T" ). |
default | &str | Yes | The fallback value returned if resolution fails (e.g., "false" , None ). |
deref_once | bool | No | If specified, the casted pointer will be dereferenced once(by read_unaligned ). |
id.se | u64 | Yes | Relocation ID for Skyrim Special Edition. |
id.ae | u64 | Yes | Relocation ID for Skyrim Anniversary Edition. |
id.vr | u64 | No | Relocation ID for Skyrim VR. Defaults to se if omitted. |
If deref_once
is specified and the cast_as
type is a multi-level pointer (e.g., *mut *mut T
),
the macro will automatically strip one level and define a helper type alias DerefType
:
type DerefType = *mut T;
This type alias can then be used as the parameter type in the closure.
§Function Body
The function body must be a single closure of the form:
|as_type: AsType| { ... }
where AsType
is either the raw casted pointer or the dereferenced value, depending on deref_once
.
If resolution fails, the default
value will be returned instead (parsed as a Rust expression).
§Examples
§Without deref_once
#[commonlibsse_ng_derive_internal::relocate(
cast_as = "*mut EntryPoint",
default = "None",
id(se = 675707, ae = 368994)
)]
#[inline]
fn entry_points(entry_point: ENTRY_POINT) -> Option<NonNull<EntryPoint>> {
|as_type| unsafe { NonNull::new(as_type.add(entry_point as usize)) }
}
§With deref_once and pointed pointer(e.g. GetSingleton
)
#[commonlibsse_ng_derive_internal::relocate(
cast_as = "*mut *mut INIPrefSettingCollection",
default = "None",
deref_once,
id(se = 524557, ae = 411155)
)]
pub fn get_singleton() -> Option<&'static INIPrefSettingCollection> {
|deref_type: DerefType| unsafe { deref_type.as_ref() }
}
§Notes
cast_as
must be a valid Rust type (pointer types encouraged for safety).deref_once
is especially useful for singletons and global pointers.- This pattern avoids boilerplate and enables declarative relocation definitions.
§See Also
#[relocate_fn]
— relocate and invoke a function with arguments instead of reading a pointer.