interoptopus 0.10.3

The polyglot bindings generator for your library (C#, C, Python, ...). 🐙
Documentation

Latest Version docs MIT Rust Rust

Interoptopus 🐙

The polyglot bindings generator for your library.

Code you write ...

use interoptopus::{ffi_function, ffi_type, inventory};

#[ffi_type]
#[repr(C)]
pub struct Vec2 {
    pub x: f32,
    pub y: f32,
}

#[ffi_function]
#[no_mangle]
pub extern "C" fn my_function(input: Vec2) {
    println!("{}", input.x);
}

inventory!(ffi_inventory, [], [my_function], [], []);

... Interoptopus generates

Language Crate Sample Output
C# interoptopus_backend_csharp Interop.cs
C interoptopus_backend_c my_header.h
Python1 interoptopus_backend_cpython_cffi reference.py
Other Write your own backend2 -

1 Using Python CFFI. 2 Create your own backend in just a few hours. No pull request needed. Pinkie promise.

Getting Started 🍼

If you want to ...

Features

  • explicit, single source of truth API definition in Rust,
  • quality-of-life patterns (e.g., slices, services, ...)
  • if your project compiles your bindings should work, *cough*
  • easy to support new languages, fully customizable,
  • no scripts needed, just cargo build + cargo test.

Gated behind feature flags, these enable:

  • derive - Proc macros such as ffi_type, ...
  • serde - Serde attributes on internal types.
  • log - Invoke log on FFI errors.

Supported Rust Constructs

See the reference project for an overview:

  • functions (extern "C" functions and delegates)
  • types (composites, enums, opaques, references, ...)
  • constants (primitive constants; results of const evaluation)
  • patterns (ASCII pointers, options, slices, classes, ...)

Performance 🏁

Generated low-level bindings are "zero cost" w.r.t. hand-crafted bindings for that language.

That said, even hand-crafted bindings encounter some target-specific overhead at the FFI boundary (e.g., marshalling or pinning in managed languages) For C# that cost can be nanoseconds, for Python CFFI it can be microseconds.

See this C# call-cost table🔥 for ballpark figures.

Changelog

  • v0.10 - C# flavors DotNet and Unity (incl. Burst).
  • v0.9 - 150x faster C# slices, Python type hints.
  • v0.8 - Moved testing functions to respective backends.
  • v0.7 - Make patterns proc macros for better FFI docs.
  • v0.6 - Renamed and clarified many patterns.
  • v0.5 - More ergonomic slice usage in Rust and FFI.
  • v0.4 - Enable logging support in auto-generated FFI calls.
  • v0.3 - Better compatibility with generics.
  • v0.2 - Introduced "patterns"; working interop for C#.
  • v0.1 - First version.

Also see our upgrade instructions.

FAQ

Contributing

PRs are welcome.

  • Submit small bug fixes directly. Major changes should be issues first.
  • Anything that makes previously working bindings change behavior or stop compiling is a major change;
  • This doesn't mean we're opposed to breaking stuff 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.