C ABI

Xenon imports and exports native functions through the platform C ABI with explicit source-level declarations.

Importing a C function

extern declares a native function implemented outside the Xenon compilation. Its declared name is used as the native symbol name.

namespace Example;

extern int puts(readonly byte* text);

int Main()
{
    puts("Hello from Xenon");
    return 0;
}

Exporting a Xenon function

export exposes a function as a native C-compatible symbol. Namespace components are flattened with underscores.

namespace Example.Math;

export int Add(int a, int b)
{
    return a + b;
}
Example.Math.AddExample_Math_Add

ABI types

Fixed-width integers, native-sized integers, C long integers, floating-point values and pointers map directly to target LLVM types.

byteshortintlongnintnuintclongculongfloatdoubleT*

C ABI boundaries use pointers for Xenon structs and arrays. Struct values are not passed to or returned from extern and export functions by value, and T[] is not an external ABI type. Pass a struct as T*; pass an array as an element pointer together with an explicit length.

extern void ProcessSamples(readonly float* samples, nuint length);

Pointer-based APIs keep ownership, bounds and layout explicit at the language boundary.

Calling from C

/* example.h */
int Example_Math_Add(int a, int b);

/* main.c */
int result = Example_Math_Add(20, 22);