hi-ffi

Crates.iohi-ffi
lib.rshi-ffi
version0.4.1
created_at2025-12-11 23:12:26.098783+00
updated_at2026-01-20 21:43:22.948684+00
descriptionProcedural macro that automatically generates FFI for C++, Python and Swift
homepagehttps://github.com/sbag13/hi-ffi
repositoryhttps://github.com/sbag13/hi-ffi
max_upload_size
id1980736
size239,535
(sbag13)

documentation

README

hi-ffi

License: MIT Rust

hi-ffi is a Rust procedural macro that automatically generates Foreign Function Interface (FFI) bindings for your Rust code, enabling seamless integration with C++, Swift and Python applications. With minimal annotations, you can expose Rust structs, functions, and methods to other languages without writing boilerplate FFI code.

Features

  • 🚀 Zero Boilerplate: Generate FFI bindings with a single #[ffi] attribute
  • 🔧 Flexible Configuration: Control getter/setter generation with field-level attributes
  • 🌐 Multi-Language Support: Generate bindings for C++ and Swift
  • 📦 Type Safety: Maintain type safety across language boundaries
  • 🎯 Selective Export: Choose which fields and methods to expose
  • 🔒 Memory Safe: Automatic memory management for cross-language calls

Installation

Add hi-ffi to your Cargo.toml:

[dependencies]
hi_ffi = { version = "0.4", features = ["cpp", "swift", "python"] }

Note: hi-ffi is a procedural macro crate. Enable the cpp and/or swift, python features based on your target languages.

Quick Start

Basic Usage

Annotate your Rust code with #[ffi] to generate FFI bindings:

use hi_ffi::ffi;

#[ffi]
#[derive(Default, Clone)]
struct Person {
    // Generate both getter and setter
    #[ffi(setter, getter)]
    age: i32,

    // Generate getter only (read-only)
    #[ffi(getter)]
    name: String,

    // Public fields automatically get getters and setters
    pub email: String,

    // Skip FFI generation for internal fields
    #[ffi(skip)]
    _internal_id: u64,
}

#[derive(Debug)]
pub struct SimpleError;
impl std::fmt::Display for SimpleError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "SimpleError")
    }
}
impl std::error::Error for SimpleError {}

#[ffi]
fn greet(names: Vec<String>) -> Result<String, SimpleError> {
    Ok(format!("Hello, {:?}!", names))
}

After building your Rust project, FFI bindings are generated in the generated_code directory, ready to be integrated into your C++, Swift or Python projects.

Language-Specific Examples

Complete working examples are available in the tests directory:

These examples demonstrate how to use the generated bindings in real applications.

Supported Features

Structs

Feature C++ Swift Python
Primitive getters/setters
String getters/setters
Struct getters/setters
Vec getters/setters
C-like Enum getters/setters
Default constructor
PartialEq

Methods

Feature C++ Swift Python
Primitive arguments
String arguments
Primitive return
String return
Struct arguments
Struct return

Static Methods

Feature C++ Swift Python
Primitive arguments
String arguments
Primitive return
String return
Struct arguments
Struct return

Functions

Feature C++ Swift Python
Primitive arguments
String arguments
Primitive return
String return
Struct arguments
Struct return
Vec arguments
Vec return
&str return

Vectors

Feature C++ Swift Python
Primitive
String
Struct
C-like enums
&str
Traits

Enums

Feature C++ Swift Python
C-like enums
Single element variants
Tuple variants

Results

Feature C++ Swift Python
Fn primitive Result
Fn struct Result
Fn string Result
Fn vec results
Fn enum Result
Methods primitive Result
Methods struct Result
Methods string Result
Methods vec results
Methods enum Result

Option

Feature C++ Swift Python
-

Architecture

hi-ffi is built with a modular architecture:

  • lib.rs - Main entry point that orchestrates code generation
  • translator - Parses Rust code into a language-agnostic intermediate representation
  • wrapper - Generates Rust glue code and target language bindings
  • Language modules (cpp, swift, python) - Generate language-specific code

The translation process:

  1. Parse Rust code marked with #[ffi]
  2. Extract type information and method signatures
  3. Generate Rust FFI wrapper functions
  4. Generate target language bindings (C++ headers, Swift code, etc.)

Generated Code Location

After building your project, generated FFI code is placed in:

generated_code/
├── rust/          # Rust FFI wrapper functions
├── cpp/           # C++ headers and implementations
├── swift/         # Swift package structure
└── python_ffi/    # python package

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Roadmap

  • Doc strings
  • Options
  • Traits
  • Async

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Built with ❤️ using Rust's powerful procedural macro system.


Note: This project is in active development. All features are experimental and subject to change.

Commit count: 35

cargo fmt