Calling C

Extern functions, headers, structs, pointers, and callbacks.

The replacement compiler checks imported C types and native call boundaries through its compiler APIs. The current source runner does not yet discover headers, configure native modules or load their libraries. A successful source check of an external declaration does not make that declaration executable.

Declare a C function

An extern fn declaration describes parameters and a result supplied outside Moon. Use types from the actual native declaration. Raw foreign calls require unsafe, and execution also requires a native binding. An incomplete-lifetime warning is not proof of safety.

Moon int is signed 32-bit, long is signed 64-bit, and float is binary64. C integer widths depend on the selected target. A Moon string is not a raw C character pointer.

Headers and libraries

Supply header paths, search roots, library linkage and target selection as native build inputs. Source directives such as @include, @link, @link_static and their platform variants are retired and rejected.

LLVM tool paths and the exact tool version belong in [toolchain.llvm] in moon.toml. That configuration does not itself import a header or load a native library. The source-level native-module configuration remains unavailable.

Calls that may block

The @blocking attribute is retired. Blocking execution needs a checked native adapter whose scheduling behavior is preserved through calls and wrappers. The replacement source API is not available yet; removing an attribute does not provide that behavior.

Out-parameters

Checked Moon views use &T and &mut T; raw foreign addresses use the imported pointer types c.Pointer<T> and c.ReadOnlyPointer<T>. Nullability is explicit in checked use, and imported raw pointers are nullable by default. A raw pointer proves no ownership or lifetime.

Only an addressable view with the appropriate access can supply an implicit view-to-pointer conversion at a supported native boundary. Raw pointer access and calls require unsafe. The caller still must honor the C function's real retention and mutation behavior; the compiler cannot infer those facts from a C prototype alone.

C-compatible structs

Foreign values use their imported names directly. Size, alignment, field offsets and packing come from the imported declaration. An ordinary Moon struct does not assert a C layout even when its field widths look similar. The handwritten @C and @packed attributes are retired.

Variadic functions

A bare trailing ... on an extern declaration describes C varargs rather than a Moon array parameter. Native promotions must agree with the target ABI and the actual function. Checking a variadic declaration alone does not make it executable in the current runner. Prefer a fixed-signature native wrapper when you control the C API.

Callbacks

A callback signature describes argument and result types, not retention, threading or quiescence. The @queued and @ffi_retain_callbacks annotations are retired. Their source API replacements are not available yet.

A retained callback needs an owning registration that keeps captures alive until the native side acknowledges that calls have stopped. A queued callback also needs queue ownership and checked payload transfer. Neither a bare extern declaration nor unsafe supplies these lifetime guarantees.

Foreign memory

Raw addresses must refer to live, correctly aligned storage with the declared access permissions. Native allocations require their matching release operation, and every access must end before release. Ownership wrappers and scoped allocation APIs must enforce these obligations; the former memory annotations cannot substitute for them.

The old foreign-memory helpers are retained as declaration-only tooling surfaces where their replacement implementation is unavailable. Do not treat their presence in completion or documentation as proof that they can execute or safely manage a foreign allocation.