Native plugins
Native plugins are dynamic libraries (.so/.dylib/.dll) using
abi_stable for a checked, versioned ABI:
at load time the library's type layouts are validated against the host's, so
mismatched versions fail with a clear error instead of undefined behaviour.
Data crosses the boundary as JSON strings — a deliberate trade: marshalling cost is negligible at plugin-call frequency, and it keeps the ABI surface tiny and forward-compatible.
The interface
loadr-plugin-api exposes #[sabi_trait] object types:
#![allow(unused)] fn main() { #[sabi_trait] pub trait FfiOutput { fn name(&self) -> RString; fn start(&mut self, config_json: RString) -> RResult<(), RString>; fn on_samples(&mut self, samples_json: RString); fn on_snapshot(&mut self, snapshot_json: RString); fn finish(&mut self, summary_json: RString); } #[sabi_trait] pub trait FfiProtocol { fn name(&self) -> RString; /// request JSON -> response JSON ({status, headers, body_base64, duration_ms, ...}) fn execute(&self, request_json: RString) -> RString; } #[sabi_trait] pub trait FfiService { fn name(&self) -> RString; fn start(&mut self, config_json: RString) -> RResult<RString, RString>; fn stop(&mut self); } }
A plugin exports one root module advertising what it provides:
#![allow(unused)] fn main() { use loadr_plugin_api::export_loadr_plugin; export_loadr_plugin! { info: my_info_fn, output: make_my_output, // any subset of output / protocol / service } }
Building
# Cargo.toml
[lib]
crate-type = ["cdylib"]
[dependencies]
loadr-plugin-api = "0.1"
abi_stable = "0.11"
cargo build --release
# package target/release/libmy_plugin.so with a plugin.toml (type = "native")
The two shipped examples are the best reference:
plugins/examples/native-output— an output plugin writing snapshot digests to a file;plugins/examples/native-protocol— anecho-protoprotocol handler, including howrequest.options.pluginconfig reaches yourexecute.
Safety notes
Native plugins run in-process with full privileges — treat them like any
dependency you compile in. Prefer WASM for anything that doesn't strictly
need native capability. loadr refuses to load a plugin whose abi_stable
layout check fails, and loadr plugin info shows what a library exports
before you enable it.