#[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_asmust be a valid Rust type (pointer types encouraged for safety).deref_onceis 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.