Generate MoonBit native C FFI declarations from C headers with Clang.
C header + config-v1/v2
│
▼
Clang 23 JSON AST ──► provenance-aware declaration model
│
typedef/enum/opaque-type environment
│
▼
ABI and policy-checked lowering
│
┌──────────────┼────────────────┐
▼ ▼ ▼
bindings.mbt optional C shim report.json (v2)moon add shop1111/moonbindgen@0.5.0import {
"shop1111/moonbindgen" @bindgen,
}let config_text =
#|{"schema":"moonbindgen-config-v1","unsupported_policy":"report"}
let config = @bindgen.parse_config(config_text)
let result = @bindgen.generate_with_config(clang_ast_json, "library.h", config)
println(result.bindings)moon run -q cmd/main -- generate fixtures/basic.h --out _build/basic --clang 'C:\Program Files\LLVM\bin\clang.exe'
moon run -q cmd/main -- generate fixtures/basic.h --out _build/basic --clang 'C:\Program Files\LLVM\bin\clang.exe' --check{
"schema": "moonbindgen-config-v1",
"include_functions": ["library_open"],
"exclude_functions": [],
"renames": { "library_open": "open_library" },
"type_overrides": { "library_size_t": "UInt64" },
"utf8_inputs": ["library_open.path"],
"unsupported_policy": "error"
}{
"schema": "moonbindgen-config-v1",
"utf8_inputs": ["sqlite3_open.filename", "sqlite3_prepare_v2.zSql"],
"output_params": ["sqlite3_open.ppDb", "sqlite3_prepare_v2.ppStmt"],
"null_inputs": ["sqlite3_prepare_v2.pzTail"],
"utf8_borrowed_returns": ["sqlite3_libversion"]
}{
"schema": "moonbindgen-config-v2",
"buffers": [{
"function": "sqlite3_bind_blob",
"pointer": 2,
"length": 3,
"direction": "in",
"retention": "copy",
"copy_parameter": 4,
"copy_symbol": "SQLITE_TRANSIENT"
}],
"return_buffers": [{
"function": "sqlite3_column_blob",
"length_function": "sqlite3_column_bytes",
"length_args": [0, 1],
"null_function": "sqlite3_column_type",
"null_symbol": "SQLITE_NULL"
}]
}{
"schema": "moonbindgen-config-v2",
"multi_outputs": [{
"function": "make_pair",
"outputs": [
{ "index": 1, "name": "left" },
{ "index": 2, "name": "right" },
{ "index": 3, "name": "handle" }
]
}],
"resources": [{
"name": "token",
"create": "token_new",
"release": "token_free",
"retain": "token_retain",
"views": ["token_borrow"]
}]
}| C declaration | MoonBit output | Policy |
|---|---|---|
| char, signed/unsigned fixed mappings | Byte, Int, UInt, Int64, UInt64 | Direct value ABI |
| float, double | Float, Double | Direct value ABI |
| typedef chains and 32-bit enums | Canonical scalar / Int | Resolved from Clang facts |
| pointer to an opaque struct typedef | #external type | Raw pointer; caller owns lifetime rules |
| configured input const char * | Bytes plus #borrow | Valid only for the duration of the call |
| configured int status plus one scalar T* or opaque T** output | (Int, T) plus generated C bridge | Explicit output parameter; no inferred cleanup |
| configured UTF-8 char* return | String? plus generated C bridge | Borrowed copy or copy and configured release |
| configured byte pointer and length | Bytes input or output plus generated C bridge | Explicit call/copy retention and capacity |
| borrowed byte pointer return and length function | Bytes? plus generated C bridge | Copied while valid; optional null discriminator |
| target-dependent scalar in config-v2 | Int, UInt, Int64, UInt64, or Bool | C bridge checks target range |
| configured multiple scalar/handle outputs | Public named result struct | Status preserved; fields initialized on failure |
| configured create/void-release handle | Managed resource and optional borrowed view | Close once, optional retain, finalizer; raw escape is explicit |
| scalar-field C value struct | Public MoonBit record plus C field bridge | Target compiler validates field accesses and direct scalar widths |
| other pointers, callbacks, variadics, complex records | none | Reported and skipped, or rejected in strict mode |
{
"schema": "moonbindgen-report-v2",
"clang": { "version": "clang version 23.1.1 ...", "target": "x86_64-pc-windows-msvc" },
"summary": { "functions_generated": 4, "functions_skipped": 0, "unsupported": 0 },
"declarations": [{ "c_name": "abi_add", "status": "generated", "reason_code": "generated" }]
}./scripts/verify.ps1moon run -q examples/sqlite
# SELECT 42 => 42
# SQLite BLOB => 3 bytes, empty, NULL#deprecated("`ConfigError::equal` is deprecated, use `Eq::equal` instead.")
fn ConfigError::equal(ConfigError, ConfigError) -> Bool#deprecated("`ConfigError::not_equal` is deprecated, use `Eq::not_equal` instead.")
fn ConfigError::not_equal(x : ConfigError, y : ConfigError) -> Bool#deprecated("`ConfigError::to_repr` is deprecated, use `@moonbitlang/core/debug.Debug::to_repr` instead.")
fn ConfigError::to_repr(ConfigError) -> Reprpub struct BufferPolicy {
function_name : String
pointer : Int
length : Int
direction : String
retention : String
copy_parameter : Int
copy_symbol : String
}pub struct GenerateConfig {
schema_version : Int
include_functions : Map[String, Bool]
exclude_functions : Map[String, Bool]
renames : Map[String, String]
type_overrides : Map[String, String]
utf8_inputs : Map[String, Bool]
output_params : Map[String, Bool]
null_inputs : Map[String, Bool]
utf8_borrowed_returns : Map[String, Bool]
utf8_owned_returns : Map[String, String]
unsupported_policy : UnsupportedPolicy
buffers : Array[BufferPolicy]
return_buffers : Array[ReturnBufferPolicy]
multi_outputs : Array[MultiOutputPolicy]
resources : Array[ResourcePolicy]
}pub struct GenerateResult {
bindings : String
report : String
shim : String?
generated : Int
skipped : Int
}pub struct NamedOutput {
index : Int
name : String
}pub struct ResourcePolicy {
name : String
create : String
release : String
retain : String
views : Array[String]
}pub struct ReturnBufferPolicy {
function_name : String
length_function : String
length_args : Array[Int]
null_function : String
null_symbol : String
}pub struct ToolMetadata {
clang_version : String
clang_target : String
}#deprecated("`UnsupportedPolicy::equal` is deprecated, use `Eq::equal` instead.")
fn UnsupportedPolicy::equal(UnsupportedPolicy, UnsupportedPolicy) -> Bool#deprecated("`UnsupportedPolicy::not_equal` is deprecated, use `Eq::not_equal` instead.")
fn UnsupportedPolicy::not_equal(x : UnsupportedPolicy, y : UnsupportedPolicy) -> Bool#deprecated("`UnsupportedPolicy::to_repr` is deprecated, use `@moonbitlang/core/debug.Debug::to_repr` instead.")
fn UnsupportedPolicy::to_repr(UnsupportedPolicy) -> Reprfn generate_with_config(ast_text : String, header : String, config : GenerateConfig) -> GenerateResult raisefn generate_with_metadata(ast_text : String, header : String, config : GenerateConfig, metadata : ToolMetadata) -> GenerateResult raiseInstall
Download zipGenerate MoonBit native C FFI declarations from C headers with Clang.