C Interop

GX is designed for seamless C integration.

Include C Headers

@c_include("stdio.h")

Extern Functions

extern fn printf:c_int(fmt:cstr, ...)

ABI Types

c_int, c_uint, c_long, c_ulong
c_size, c_ssize
c_char, c_uchar
c_bool, c_void
cstr (raw const char* — auto-converts to/from str at function boundaries)

Extern Struct

extern struct sapp_desc {
    width: c_int
    height: c_int
}

Function Pointers in Structs

GX supports function pointer fields inside extern struct definitions.

extern struct sapp_desc {
    init_cb: fn()
    frame_cb: fn()
    cleanup_cb: fn()
    width: c_int
    height: c_int
}

Function pointer syntax:

  • fn() --- void function
  • fn:c_int() --- returns c_int
  • fn(c_int, c_int) --- takes parameters

Extern Enum

Bind to existing C enums defined in headers.

@c_prefix("SAPP_")
extern enum sapp_keycode {
    KEYCODE_INVALID = 0
    KEYCODE_SPACE   = 32
    KEYCODE_ESCAPE  = 256
}

The @c_prefix("SAPP_") directive maps GX names to C names by prepending the prefix: KEYCODE_SPACESAPP_KEYCODE_SPACE.

For members where the prefix + name doesn’t match the C name, use @c_name to override:

@c_prefix("SAPP_")
extern enum sapp_keycode {
    KEYCODE_0 = 48 @c_name("SAPP_KEYCODE_0")
    KEYCODE_1 = 49 @c_name("SAPP_KEYCODE_1")
}
  • Members separated by newlines (commas optional)
  • = value is optional, for documentation and matching C header values
  • @c_name("...") overrides the generated C name for individual members
  • @c_prefix("...") applies to the entire enum

C-ABI Callable

@c_abi
fn callback() {}