Crate interoptopus[−][src]
Expand description
Interoptopus
C#, Python, C, … → 🐙 → 🦀
FFI from your favorite language to Rust. Escape hatchets included.
Overview
If you …
- have an
extern "C"
API in Rust, - need C#, Python, C, … bindings to your library,
- prefer having fine-grained-control over your API and interop generation,
- would like to use quality-of-life patterns on both sides (e.g., options, slices, ‘classes’) where feasible,
- might need to swiftly support a new language,
- think your FFI single source of truth should be living Rust code,
… then Interoptopus might be for you.
Known Limitations
- not yet used in production
- a bit verbose if you don’t own 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
Rust Code You Write
This is code you would write:
use interoptopus::{ffi_function, ffi_type}; #[ffi_type] #[repr(C)] pub struct Vec3 { pub x: f32, pub y: f32, pub z: f32, } #[ffi_function] #[no_mangle] pub extern "C" fn my_function(input: Vec3) -> Vec3 { Vec3 { x: 2.0, y: 4.0, z: input.z } } interoptopus::inventory_function!(ffi_inventory, [], [my_function], []);
Generated Code
Once you’ve written the code above you use one of these backends to generate interop code:
Language | Crate | Sample Output |
---|---|---|
C# (incl. Unity) | interoptopus_backend_csharp | Interop.cs |
C | interoptopus_backend_c | my_header.h |
Python CFFI | interoptopus_backend_cpython_cffi | reference.py |
Your language | Write your own backend! | - |
Features
See the reference project lists all supported constructs including:
- functions (
extern "C"
functions and delegates) - types (primitives, composite, enums (numeric only), opaques, references, pointers, …)
- constants (primitive constants; results of const evaluation)
- patterns (ASCII pointers, options, slices, classes, …)
As a rule of thumb we recommend to be slightly conservative with your signatures and always “think C”, since other languages don’t track lifetimes
well and it’s is easy to accidentally pass an outlived pointer or doubly alias a &mut X
on reentrant functions.
Current Status
- June 20, 2021 - Alpha. Has generated simple workingTM bindings for a few projects for a week now, many things missing.
- June 13, 2021 - Pre-alpha. Has generated C#, C, Python-CFFI bindings at least once, many things missing, untested.
FAQ
Contributing
PRs are welcome.
-
Bug fixes can be submitted directly. Major changes should be filed as issues first.
-
Anything that would make previously working bindings change behavior or stop compiling is a major change; which doesn’t mean we’re opposed to breaking stuff before 1.0, just that we’d like to talk about it before it happens.
-
New features or patterns must be materialized in the reference project and accompanied by an interop test (i.e., a backend test running C# / Python against a DLL invoking that code) in at least one included backend.
Modules
lang | Abstractions for authors of backends. |
patterns | Optional types that translate to binding with better semantics in languages supporting them. |
testing | testing Test generated bindings for various languages. |
util | Helpers for backend authors. |
writer | Types used by backends to produce pretty output. |
Macros
inventory_function | derive The macro to define your library, ties everything together! |
pattern_class_generated | Defines a |
pattern_class_manual | Defines a |
Structs
Library | Represents all FFI-relevant items, produced via |
Enums
Error | Can be observed if something goes wrong. |
Traits
Interop | Main entry point for backends to generate language bindings. |
Attribute Macros
ffi_constant | derive Enables a |
ffi_function | derive Enable an |
ffi_type | derive Enable a |