Heroes / Esempi / 08-ffi

examples/gallery/08-ffi.hero

Come usare le librerie C per le funzioni che Heroes non include.

Con extern puoi usare funzioni matematiche, leggere file, comunicare in rete e accedere a database. Clang, il compilatore C, verifica ogni dichiarazione sull’header originale, il file che descrive le funzioni della libreria. Se un tipo non corrisponde, la compilazione si ferma con un errore.

Eseguilo

$ heroes run examples/gallery/08-ffi.hero

Questo esempio serve a illustrare il linguaggio. Qui trovi il programma e non un risultato: non ci sono ancora test che confrontino il suo output byte per byte.

Il programma

## Everything else comes from C
#
# There is no standard library, permanently. Maths beyond arithmetic,
# files, sockets, databases: they arrive through `extern`, and clang checks
# every declaration against the real header — a wrong type here is a
# compile error, not a crash at runtime.
#
# A group names the header its signatures come from. That is not decoration:
# the header is what clang checks against, and without one a declaration
# would be verified by nothing at all.

extern "math.h" link "m"
    function sqrt(x: f64) -> f64
    function pow(base: f64, exponent: f64) -> f64
    function floor(x: f64) -> f64

# `cstr` is a C string and `ptr` an opaque pointer. Neither is a `str`:
# the boundary is visible in the type. A second group, because this one
# comes from a different header — and on macOS neither needs `link`, since
# libm and libc are already there.
extern "stdio.h"
    function puts(s: cstr) -> i64

# The hypotenuse, in the language's own arithmetic plus one C call.
#
# Both sides are `f64`, so §4.9 makes the names mandatory at the call site. C's
# numeric APIs are where same-typed parameters cluster — `pow(base:, exponent:)`
# is the same shape — so this is where the rule is felt most and where argument
# inversion would be silent without it.
function hypotenuse(a: f64, b: f64) -> f64
    return sqrt(a * a + b * b)

# No implicit conversions: an `i64` becomes an `f64` because you said so.
function diagonal_of(width: i64, height: i64) -> f64
    return hypotenuse(a: to_f64(width), b: to_f64(height))

# `pow` is C's, `floor` is C's, and the rounding is yours.
function rounded_power(base: f64, exponent: f64) -> i64
    return to_i64(floor(pow(base: base, exponent: exponent))).must()

test "the C library does the maths"
    assert hypotenuse(a: 3.0, b: 4.0) == 5.0
    assert rounded_power(base: 2.0, exponent: 10.0) == 1024

function main()
    print(
        "the 16:9 diagonal of a 1920-wide screen: ",
        diagonal_of(width: 1920, height: 1080)
    )
examples/gallery/08-ffi.hero, 49 righe

impronta sha256 1c123e67ca74 · 1 file · index.json

Successivo: 09-holes. Tutti gli esempi. ← Precedente: 07-strings

Eseguine uno: i quattro comandi. Impara il linguaggio, oppure leggi la specifica completa in un solo file.