Skip to main content

anvil_sys/
lib.rs

1//! Raw bindings to the Anvil plugin API 2 (`include/anvil/anvil_plugin.h`)
2//! and to the services Anvil ships (`anvil_game.h`, `anvil_panel.h`,
3//! `anvil_benchmark.h`). The safe API on top of it is the `anvil-sdk` crate.
4//!
5//! The items of `bindings.rs` are generated by `bindgen`; this file adds what a
6//! header cannot say: the type of the one function a plugin exports and
7//! compile-time checks of the layouts the host and the plugin share.
8#![no_std]
9
10#[allow(
11    non_camel_case_types,
12    non_snake_case,
13    non_upper_case_globals,
14    clippy::all,
15    clippy::pedantic,
16    clippy::nursery,
17    rustdoc::all
18)]
19#[rustfmt::skip]
20mod bindings;
21
22pub use bindings::*;
23
24/// The type of `anvil_plugin_load`, which every plugin exports (`extern "C"`,
25/// not mangled): `#[unsafe(no_mangle)] pub unsafe extern "C" fn anvil_plugin_load(…)`.
26pub type AnvilPluginLoadFn =
27    unsafe extern "C" fn(host: *const AnvilHost, self_: *mut AnvilPlugin) -> AnvilResult;
28
29// The context is exactly SafetyHook's `Context64`: XMM0-15 (256 bytes), then
30// RFLAGS, the 15 general registers, `rsp`, a reserved slot and `rip`.
31const _: () = {
32    use core::mem::{align_of, offset_of, size_of};
33    assert!(size_of::<AnvilCpuContext>() == 408);
34    assert!(align_of::<AnvilCpuContext>() == 8);
35    assert!(size_of::<AnvilXmm>() == 16);
36    assert!(offset_of!(AnvilCpuContext, xmm) == 0);
37    assert!(offset_of!(AnvilCpuContext, rflags) == 256);
38    assert!(offset_of!(AnvilCpuContext, rax) == 256 + 14 * 8);
39    assert!(offset_of!(AnvilCpuContext, rsp) == 256 + 16 * 8);
40    assert!(offset_of!(AnvilCpuContext, rip) == 256 + 18 * 8);
41    assert!(ANVIL_API_VERSION == 2);
42    // Pointer-sized fields: this is an x86-64 interface.
43    assert!(size_of::<usize>() == 8);
44};