Das Foreign Function Interface (FFI) erlaubt es Lyx-Programmen, Funktionen aufzurufen, die in anderen Programmiersprachen (primär C) geschrieben wurden, und Daten mit ihnen auszutauschen. Dies ist notwendig für die Nutzung von System-APIs (POSIX, Win32) oder spezialisierten Mathematik-Bibliotheken.
Um eine C-Funktion aufzurufen, muss sie in Lyx deklariert werden. Das Attribut @extern teilt dem Compiler mit, dass die Implementierung nicht in Lyx vorliegt, sondern beim Linken in einer externen Objektdatei oder Bibliothek gesucht werden muss.
// Deklaration der C-Funktion 'printf' aus der Standard-C-Lib
@extern
fn printf(format: pchar, val: int64): int32;
fn main() {
printf("Zahl aus C: %d\n", 42);
}
Beim FFI ist es entscheidend, dass die Bit-Breiten der Typen übereinstimmen.
| Lyx Typ | C Äquivalent | Beschreibung |
|---|---|---|
int8 | int8_t / char | 8-Bit Ganzzahl |
int32 | int32_t / int | 32-Bit Ganzzahl |
pchar | char* | Nullterminierter String-Pointer |
^void | void* | Generischer Pointer |
type S = struct | struct S | Strukturen (nutze @packed) |
C-Compiler fügen oft „Padding“ (Füllbits) zwischen Strukturfeldern ein, um den Zugriff zu beschleunigen. Lyx macht das standardmäßig auch. Wenn eine Hardware-Struktur oder eine C-Bibliothek ein exaktes Layout ohne Lücken erwartet, muss das Attribut @packed verwendet werden.
@packed
type CStruct = struct {
id: uint8, // 1 Byte
value: uint32 // 4 Bytes, direkt nach id ohne 3 Bytes Padding
}
Ein häufiger Fehler im FFI ist das Management von Strings.
pchar in Lyx ist bereits ein nullterminierter String-Pointer und kann direkt an C-Funktionen übergeben werden.free() in C vs. dispose in Lyx).@extern
fn get_os_username(): pchar;
fn print_user() {
let name: pchar := get_os_username();
PrintStr(name);
// Achtung: Wenn C den Speicher allokiert hat, darf Lyx ihn nicht disposen!
}
Lyx kann Funktionspointer an C übergeben, damit C Lyx-Code aufruft (Callbacks). Dies ist bei GUI-Bibliotheken oder asynchronen Treibern üblich.
type TimerCallback = fn(delta: f64);
@extern
fn SetTimer(ms: int32, callback: TimerCallback);
fn MyTimerTick(delta: f64) {
PrintStr("Tick!");
}
fn start() {
SetTimer(1000, MyTimerTick);
}
FFI-Aufrufe gelten in Lyx grundsätzlich als unsafe, da der Compiler nicht prüfen kann, was innerhalb der C-Bibliothek passiert (z. B. Speicherverletzungen oder Null-Pointer-Dereferenzierung).
DO-178C Hinweis:
In hochkritischen Systemen (DAL A/B) müssen FFI-Schnittstellen durch „Wrapper“ gekapselt werden, die Eingangsdaten validieren, bevor sie an die externe C-Funktion gereicht werden.