savefile-abi

Crates.iosavefile-abi
lib.rssavefile-abi
version0.17.4
sourcesrc
created_at2024-04-09 21:53:00.704429
updated_at2024-05-12 20:57:36.008021
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
size75,910
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.

savefile-abi = "0.17"
savefile = "0.17"
savefile-derive = "0.17"

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: 423

cargo fmt