Inhaltsverzeichnis

std.res — eingebettete Ressourcen

import std.res;

Zugriff auf Dateien, die mit @resource(„name“, „pfad“) ins Erzeugnis eingebettet wurden — über ihren Namen, zur Laufzeit. Das Gegenstück zu Delphis .res: Bilder, Schriften, Vorlagen oder Konfigurationsvorgaben liegen im Programm selbst, nicht daneben im Dateisystem.

@resource und @embed · Standard Library · #1961


1. Einbetten und finden

unit main;
@resource("splash", "assets/splash.lyxi");
@resource("hilfe",  "assets/hilfe.txt");

import std.res;
import std.io;
import std.string;

fn main(): int64 {
    var bild: pchar := ResFind("splash");
    var n:    int64 := ResLen("splash");

    PrintLn(StrConcat("Groesse: ", IntToStr(n)));
    PrintLn(StrConcat("Inhalt:  ", bild));
    return 0;
}

Groesse: 16
Inhalt:  SPLASH-BYTES-123

@resource steht auf Unit-Ebene, nicht in einer Funktion. Der Pfad wird relativ zur Quelldatei aufgelöst, nicht zum Arbeitsverzeichnis — ein Programm lässt sich also aus jedem Verzeichnis übersetzen.


2. Funktionen

Signatur Zweck
ResCount(): int64 Zahl der eingebetteten Ressourcen; 0, wenn keine vorhanden
ResFind(name: pchar): pchar Zeiger auf die Bytes, oder 0 bei unbekanntem Namen
ResLen(name: pchar): int64 Länge in Byte, oder 0
ResIndex(name: pchar): int64 Position in der Tabelle, oder -1
ResName(i: int64): pchar Name des Eintrags i
ResBytesAt(i: int64): pchar Bytes des Eintrags i
ResSizeAt(i: int64): int64 Länge des Eintrags i

Damit lässt sich der Bestand auch durchlaufen — etwa für ein Werkzeug, das zeigt, was in einem Programm steckt:

var i: int64 := 0;
while (i < ResCount()) {
    PrintLn(StrConcat(ResName(i), StrConcat("  ", IntToStr(ResSizeAt(i)))));
    i := i + 1;
}


3. Aufbau der Tabelle

Die Tabelle liegt im Datensegment und wird über das Builtin GetResTable() erreicht — dasselbe Muster wie GetEnvBlock (#1677): der Codegen kennt die Adresse, std/res.lyx rechnet in Lyx weiter. Damit ist die Bibliotheksseite lesbarer Lyx-Code und kein Compiler-Interna.

[0]              Anzahl der Einträge
[1 + i*4 + 0]    Zeiger auf den Namen (NUL-terminiert)
[1 + i*4 + 1]    Länge des Namens
[1 + i*4 + 2]    Zeiger auf die Bytes
[1 + i*4 + 3]    Anzahl der Bytes

GetResTable() liefert 0, wenn das Programm keine einzige @resource-Angabe trägt. Jede Funktion dieser Unit fängt diesen Fall ab — ein Programm ohne Ressourcen bekommt ResCount() = 0 und keinen Absturz.


4. Fallstricke

<WRAP center round important 90%> Nur --target=x86_64. Auf dem IR-Weg (lyxos, arm64, riscv, xtensa) bricht die Übersetzung ab:

lyxc: @resource ist bisher nur mit --target=x86_64 umgesetzt.
  Die Ressourcentabelle besteht aus Zeigern in den Datenbereich; auf dem
  IR-Weg gibt es dafuer bisher nur die nullterminierte
  Zeichenkettentabelle (siehe #1968).

Für einzelne Dateien geht dort @embed — bei Textdateien. </WRAP>


5. Abgrenzung zu @embed

@embed(„pfad“) @resource(„name“, „pfad“)
Auflösung zur Übersetzungszeit, der Pfad steht im Quelltext zur Laufzeit, über den Namen
Ergebnis Zeiger auf die Bytes (@embed_len liefert die Größe) Eintrag in einer benannten Tabelle
Auflisten möglich nein ja, über ResCount/ResName
Name zur Laufzeit wählbar nein ja
Zielplattformen auch IR-Ziele (Textdateien) nur x86-64

@embed ist der kürzere Weg, wenn genau eine Datei an genau einer Stelle gebraucht wird:

var s: pchar := @embed("assets/hilfe.txt");
var n: int64 := @embed_len("assets/hilfe.txt");

 
Warum ein Zeiger und kein [N]uint8-Feld: Lyx legt Felder mit acht Byte je Element ab, auch bei uint8. Ein eingebettetes 1-MB-Bild bräuchte damit 8 MB im Erzeugnis. Die Bytes liegen deshalb gepackt im Datensegment, und @embed liefert die Adresse. Gelesen wird mit peek8, wie bei jedem anderen Bytepuffer.

Letzte Aktualisierung: 2026-09-05 — Seite neu angelegt; erhoben aus std/res.lyx und src/parser.lyx (#1961 Stufe 1 und 2), alle Beispiele gegen lyxc 1.2.2D übersetzt und ausgeführt.

Ressourcen in einer ''.lyu''

Seit #1971 trägt auch das .lyu-Format eingebettete Ressourcen: der Abschnitt steht am Ende der Datei, der Offset im bisher reservierten Feld des Kopfes. Die Version bleibt 2 — ein Leser, der den Abschnitt nicht kennt, hört nach der Symboltabelle auf und liest die Datei unverändert.

--unit-info listet die Ressourcen mit Name und Größe. Das ist die Stelle, an der sich ohne Übersetzen nachsehen lässt, was eine Bibliothek mitbringt.

Die Länge steht ausdrücklich in der Datei und nicht als Nullterminierung: eine Ressource ist eine Binärdatei und darf Nullbytes tragen — genau daran ist die Zeichenkettentabelle des IR-Wegs gescheitert (#1968).

 
Der Import daraus fehlt noch. Eine .lyu trägt die Ressourcen zwar, aber eine importierende Übersetzung übernimmt sie nicht — das hängt an #2014, solange die .lyu eine reine Namensliste ist. Offen sind ebenso die IR-Ziele und das LBF-Format.