savefile-abi

Crates.iosavefile-abi
lib.rssavefile-abi
version0.18.4
sourcesrc
created_at2024-04-09 21:53:00.704429
updated_at2024-11-04 20:34:29.710944
descriptionEasy to use, simple, stable ABI for Rust-libraries. Allows creating dynamically loadable plugins written in rust.
homepagehttps://github.com/avl/savefile/blob/master/savefile-abi/README.md
repositoryhttps://github.com/avl/savefile
max_upload_size
id1202877
size89,078
Anders Musikka (avl)

documentation

https://docs.rs/savefile-abi/

README

Welcome to Savefile-abi!

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"

Example

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);
}

Limitations

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/

Commit count: 453

cargo fmt