Crates.io | savefile-abi |
lib.rs | savefile-abi |
version | 0.18.4 |
source | src |
created_at | 2024-04-09 21:53:00.704429 |
updated_at | 2024-11-04 20:34:29.710944 |
description | Easy to use, simple, stable ABI for Rust-libraries. Allows creating dynamically loadable plugins written in rust. |
homepage | https://github.com/avl/savefile/blob/master/savefile-abi/README.md |
repository | https://github.com/avl/savefile |
max_upload_size | |
id | 1202877 |
size | 89,078 |
Full docs: https://docs.rs/savefile-abi/latest/
Savefile-abi is a crate that is primarily meant to help building binary plugins using Rust. It supports many data types from the standard library, as well as custom user types.
It supports async methods, through use of the #[async_trait] attribute macro.
savefile-abi = "0.18"
savefile = "0.18"
savefile-derive = "0.18"
Let's say we have a crate that defines this trait for adding u32s:
interface_crate
use savefile_derive::savefile_abi_exportable;
#[savefile_abi_exportable(version=0)]
pub trait AdderInterface {
fn add(&self, x: u32, y: u32) -> u32;
}
Now, we want to implement addition in a different crate, compile it to a shared library (.dll or .so), and use it in the first crate (or some other crate):
implementation_crate
use interface_crate::{AdderInterface};
use savefile_derive::savefile_abi_export;
#[derive(Default)]
struct MyAdder { }
impl AdderInterface for MyAdder {
fn add(&self, x: u32, y: u32) -> u32 {
x + y
}
}
// Export this implementation as the default-implementation for
// the interface 'AdderInterface', for the current library.
savefile_abi_export!(MyAdder, AdderInterface);
We add the following to Cargo.toml in our implementation crate:
[lib]
crate-type = ["cdylib"]
Now, in our application, we add a dependency to interface_crate, but not to ImplementationCrate.
We then load the implementation dynamically at runtime:
app
use savefile_abi::{AbiConnection};
use interface_crate::{AdderInterface};
fn main() {
// Load the implementation of `dyn AdderInterface` that was published
// using the `savefile_abi_export!` above.
let connection = AbiConnection::<dyn AdderInterface>
::load_shared_library("./ImplementationCrate.so").unwrap();
// The type `AbiConnection::<dyn AdderInterface>` implements
// the `AdderInterface`-trait, so we can use it to call its methods.
assert_eq!(connection.add(1, 2), 3);
}
There are multiple limitations:
Tuples are presently not supported as direct function arguments!
There may be safety issues, Savefile-Abi is not mature yet.
See full docs: https://docs.rs/savefile-abi/latest/