Crate interoptopus[−][src]
Expand description
Interoptopus
Create FFI bindings to your favorite language. Composable. Escape hatches included.
Overview
- you wrote an
extern "C"
API in Rust - the types at the FFI boundary are (mostly) owned by yourself
- you prefer to keep all your binding-related information (e.g., documentation) in Rust code
Known limitations
- not used in production yet
- somewhat verbose if you don’t own most of your types (still possible, just more work)
- if you target only a single language and don’t care about your FFI layer other solutions might be better
Supported Languages
Language | Crate | Comment |
---|---|---|
C# | interoptopus_backend_csharp | Built-in. |
C | interoptopus_backend_c | Built-in. |
Python CFFI | interoptopus_backend_cpython_cffi | Built-in. |
Your language | Write your own backend! | See existing backends for what to do.* |
(*) Ok, right now I don’t really recommend writing a new backend just yet as lots of internals might change. That said, it should only take a few hours and feedback is more than welcome.
Example
Slightly abridged, see the examples/hello_world
for full code:
use interoptopus::{ffi_function, ffi_type}; use interoptopus_backend_csharp::Interop; #[ffi_type] #[repr(C)] pub struct Vec2f32 { pub x: f32, pub y: f32, pub z: f32, } /// A function which does something with the vector. #[ffi_function] #[no_mangle] pub extern "C" fn my_game_function(input: Option<&Vec2f32>) -> Vec2f32 { Vec2f32 { x: 2.0, y: 4.0, z: 6.0 } } // This ultimately defines our FFI exports, all functions have to be listed here. interoptopus::inventory_function!(ffi_inventory, [], [my_game_function]); #[test] fn generate_csharp_bindings() { use interoptopus::writer::IndentWriter; let library = ffi_inventory(); let config = interoptopus_backend_csharp::Config { namespace: "My.Company".to_string(), class: "InteropClass".to_string(), dll_name: "hello_world".to_string(), ..interoptopus_backend_csharp::Config::default() }; let generator = interoptopus_backend_csharp::Generator::new(config, library); generator.write_to(my_file)?; }
With a Cargo.toml:
[dependencies]
interoptopus = { version = "0.1", features = ["derive"] }
interoptopus_backend_csharp = "0.1"
Will produce:
using System;
using System.Runtime.InteropServices;
namespace My.Company
{
public static class InteropClass
{
public const string NativeLib = "hello_world";
/// A function which does something with the vector.
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "my_game_function")]
public static extern Vec2f32 my_game_function(ref Vec2f32 input);
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public partial struct Vec2f32
{
public float x;
public float y;
public float z;
}
}
For other languages (Python, C, …) see examples
folder.
Modules
lang | Abstractions for authors of backends. |
util | Helpers for backend authors. |
writer | Types used by backends to produce pretty output. |
Structs
Library | Represents all FFI-relevant items, produced via [ |
Enums
Error | Can be observed if something goes wrong. |