What It Is

The MetaFFI host compiler is an optional toolchain step that generates typed host-language wrappers for a foreign module. Instead of writing entity paths and type arrays by hand, you get a generated module you can import and call directly.

Benefits:

  • Type safety — generated functions have typed signatures
  • IDE autocomplete — your editor sees real functions, not opaque callables
  • No stringly-typed code — entity paths and type arrays are handled for you
  • Fewer runtime mistakes — type mismatches caught at generation time

The generated stubs call MetaFFI under the hood. Same runtime behavior, different ergonomics.

When to Use Each Mode

  Dynamic Loading Generated Stubs
Best for Exploration, quick scripts, prototyping Production codebases, large projects, CI
Setup None — load and call at runtime One-time metaffi -c command
Entity paths Written by hand in app code Generated for you
Type arrays Written by hand in app code Generated for you
IDE support Limited (opaque callables) Full (typed functions, autocomplete)
Performance Same Same (stubs are thin wrappers)

Both modes use the same MetaFFI runtime. Stubs do not change runtime overhead — they change developer experience.

How It Works

  1. The host compiler reads a foreign module’s interface (via MetaFFI’s IDL layer)
  2. It emits host-language source code containing typed wrapper functions
  3. Each wrapper function calls MetaFFIModule.load_entity() under the hood
  4. You import the generated module and call functions normally
Source file (e.g., hello.go)
    │
    ▼
metaffi -c --idl hello.go -h python3
    │
    ▼
hello_MetaFFIHost.py  (generated stubs)
    │
    ▼
import hello_MetaFFIHost as hello
hello.SayHello("Python")

End-to-End Example: Call Go from Python

This example generates Python stubs for a Go module and calls it with typed functions.

Prerequisites

  • MetaFFI installed (Getting Started)
  • Go and Python3 language plugins installed

1. Write the Go module

Create hello.go:

package main

import "fmt"

func SayHello(name string) string {
    return fmt.Sprintf("Hello, %s! Greetings from Go.", name)
}

2. Compile and generate stubs

# Compile Go module for MetaFFI (guest) AND generate Python host stubs
metaffi -c --idl hello.go -g go -h python3

This produces:

  • hello_MetaFFIGuest.dll (or .so on Linux) — the compiled Go guest module
  • hello_MetaFFIHost.py — typed Python stubs

3. Use the generated stubs

Create main.py:

import hello_MetaFFIHost as hello

hello.bind_module_to_code("hello_MetaFFIGuest", "go")

result = hello.SayHello("Python")
print(result)  # "Hello, Python! Greetings from Go."

Compare this to the dynamic loading version — no entity paths, no type arrays, just a function call.

4. Regenerate when the Go API changes

If you modify hello.go (add functions, change signatures), re-run the same command:

metaffi -c --idl hello.go -g go -h python3

The stubs are regenerated to match the updated API.

What the Generated Code Looks Like

The host compiler generates a Python module with:

  • A bind_module_to_code(module_path, runtime_plugin) initialization function
  • Typed wrapper functions for each exported function
  • Classes for types that have constructors and instance methods
  • Property accessors for fields and global variables

Example generated code (simplified):

# Generated by MetaFFI host compiler — do not edit

import metaffi

_runtime = None
_module = None
_say_hello_caller = None

def bind_module_to_code(module_path: str, runtime_plugin: str) -> None:
    global _runtime, _module, _say_hello_caller
    _runtime = metaffi.MetaFFIRuntime(runtime_plugin)
    _runtime.load_runtime_plugin()
    _module = _runtime.load_module(module_path)
    _say_hello_caller = _module.load_entity(
        "callable=SayHello",
        (metaffi_type_info(metaffi_string8_type, "string", 0),),
        (metaffi_type_info(metaffi_string8_type, "string", 0),))

def SayHello(name: str) -> str:
    return _say_hello_caller(name)

The generated stubs handle all the entity path and type plumbing. Your application code just calls SayHello(name).

Supported Host Languages

The host compiler generates stubs for all supported MetaFFI languages:

Host Language Output Source
Python 3 .py module lang-plugin-python3/compiler
Go .go source file lang-plugin-go/compiler
JVM .jar with compiled classes lang-plugin-openjdk/compiler

CLI Reference

# Guest compilation only (compile foreign module)
metaffi -c --idl <source_file> -g <guest_language>

# Host compilation only (generate stubs)
metaffi -c --idl <source_file> -h <host_language>

# Both at once
metaffi -c --idl <source_file> -g <guest_language> -h <host_language>

# Generate stubs for multiple host languages
metaffi -c --idl <source_file> -g <guest_language> -h python3 go
Flag Description
-c Compile mode
--idl <file> Source file or IDL JSON to compile
-g <language> Guest language (produces _MetaFFIGuest library)
-h <language...> Host language(s) (produces _MetaFFIHost stubs)

See Also

  • Getting Started — installation and first cross-language call
  • Examples — code examples showing both modes
  • API Reference — the dynamic loading API used under the hood
  • Entity Path — entity path format (used by dynamic mode; generated for you in stub mode)