Expand description
§Interoptopus 🐙
Productive, performant, robust interop for Rust. Pick three.
With Interoptopus you can write code like this:
#[ffi(service)]
pub struct Hello {}
#[ffi]
impl Hello {
pub fn world() -> Result<Self, Error> { Ok(Self {}) }
}and then call it from your other language like this:
var service = Hello.World();Its key features include:
- Nanosecond fast.
- Supports structs, data-enums, callbacks, services, async, idiomatic error handling, and much more …
- Bidirectional interop, export your Rust library, or load foreign code into your Rust app.
- Painless workflow, no external tooling required.
- Polyglot core, first-class support for C#, can support any other language.
§Getting Started
Read our documentation here.
§Feature Flags
Gated behind feature flags, these enable:
macros- Proc macros such as#[ffi].serde- Serde attributes on internal types.tokio- Convenience support for async services via Tokio.unstable-plugins- Experimental ‘reverse interop’ plugins. Not semver stable!
§Supported Languages
| Language | Backend Crate | Status |
|---|---|---|
| C# | interoptopus_csharp | ✅ |
| C | interoptopus_c | ⏯️ |
| Python | interoptopus_cpython | ⏯️ |
| Other | Write your own backend1 |
✅ Tier 1 target. Active maintenance and production use. Full support of all features.
⏯️ Tier 2 target. Currently suspended, contributors wanted!
1 You can implement basic support for a new language in just a few hours, no pull request needed.
§Performance
In essence, plain calls are near-zero overhead (1-10ns), as are most structs, enums and services. If serialization is involved it scales with payload size. Using the .NET runtime as a plugin adds ~20 MB overhead.
For more details see our benchmark numbers here.
§Further Reading
§Contributing
PRs are very welcome!
- Submit small bug fixes directly. Major changes should be issues first.
- New features or patterns must be materialized in the reference project and accompanied by at least a C# interop test.
Modules§
- ffi
- FFI-safe replacements for common Rust standard library types.
- inventory
- Collection of all FFI items a library wants to expose.
- lang
- Data model describing the items of an FFI boundary.
- pattern
- Convenience patterns like strings, results and options.
- rt
tokio - Pre-built async runtimes for FFI services.
- telemetry
- Per-call telemetry for plugins.
- wire
- Serialize complex objects into flat byte buffers and transfer them over FFI.
Macros§
- builtins_
string - Emits and registers helpers for
ffi::String. - builtins_
vec - Emits and registers helpers for
ffi::Vec<T>types. - builtins_
wire - Emits and registers helpers for
Wire<T>. - callback
- Defines a callback type, akin to a
fn f(T) -> Rwrapped in anOption. - constant
- Registers a constant with the inventory.
- extra_
type - Registers an additional type with the inventory.
- function
- Registers a function with the inventory.
- guard
- Creates and registers an API guard for the current library.
- plugin
macrosandunstable-plugins - Declares a plugin interface for reverse interop, e.g., loading a C# DLL from Rust.
- service
- Registers a service with the inventory.
Structs§
- Error
- Can be observed if something goes wrong.
Attribute Macros§
- ffi
macros - Marks a Rust item for FFI export and generates the required interop metadata.
Derive Macros§
- Async
Runtime macros - Derives the
AsyncRuntimetrait for a service struct by forwarding to one of its fields.