Crate interoptopus[−][src]
Expand description
Interoptopus š
The polyglot bindings generator for your library (C#, C, Python, ā¦)
Huh?
- Imagine you are writing this cool API and want everyone to use it.
- Everyone else, however, is running Unity, C, Python, ā¦
- āNot a problemā, you say, āIāll just use Interoptopusā.
And youāll live happily* ever after.
*Actual results may depend on other life choices.
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# (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 backend1 | - |
1 Create your own backend in just a few hours. No pull request needed. Pinkie promise.
Getting Started š¼
If you ā¦
- want to create a new API see the example projects,
- need to support a new language or rewrite a backend, copy and adapt the C backend.
Features
- explicit, type-safe, single source of truth API definition in Rust,
- quality-of-life patterns on both sides (e.g., options, slices, services, ā¦)
- minimal on dependencies, build time, tooling impact,
- if your project compiles your bindings should work*cough* (i.e., generated and callable),
- extensible, multiple backends, easy to support new languages, fully customizable,
- no scripts needed,
cargo build
+cargo test
can produce and test (if lang installed) generated bindings
Gated behind feature flags, these enable:
derive
- Proc macros such asffi_constant
,ffi_function
,ffi_type
.testing
- Functions to test generated Python, C#, C from Unit tests.serde
- Serde attributes on internal types.log
- Invokelog
on FFI errors (you still need actual logger).
Supported Rust Constructs
See the reference project; it 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.
Performance š
Generated low-level bindings should be āzero costā w.r.t. hand-crafted bindings for that language. However, even hand-crafted bindings have an inherent, language-specific cost. For C# that cost can be almost 0, for Python CFFI it can be high. Patterns and convenience helpers might add additional overhead.
If you need API design guidance the following (wip) C# call-cost tableš„ can help.
Changelog
- v0.3 - Better compatibility with generics.
- v0.2 - Introduced āpatternsā; produces generally working interop for C#.
- v0.1 - Has generated C#, C, Python-CFFI bindings at least once.
FAQ
Contributing
PRs are welcome.
- Bug fixes can be submitted directly. Major changes should be filed as 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.
Modules
Abstractions for authors of backends.
Optional types that translate to binding with better semantics in languages supporting them.
testing
Test generated bindings for various languages.
Helpers for backend authors.
Types used by backends to produce pretty output.
Macros
Debug macro resolving to the current file and line number.
Writes a line of code, possibly with multiple indentations. Used in backends.
The macro to define your library, ties everything together!
Defines a new API entry function and corresponding struct.
Defines a helper function ensuring the bindings match the used DLL.
Defines a callback type, akin to a fn f(T) -> R
wrapped in an Option.
Defines a Service
pattern and generate FFI wrapper code.š§
Defines a Service
pattern, usually producing a class in OO languages.š§
Structs
Enums
Can be observed if something goes wrong.
Traits
Main entry point for backends to generate language bindings.
Functions
Create a single Library
from a number of individual libraries.
Attribute Macros
derive
Enables a const
to appear in generated bindings.
derive
Enable an extern "C"
function to appear in generated bindings.
derive
Enable a struct
or enum
to appear in generated bindings.