====== 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. → [[lyx_-_programmiersprache:sprache:attributes-pragmas#resource_und_embed|@resource und @embed]] · [[lyx_-_programmiersprache:units|Standard Library]] · [[https://github.com/SEOLizer/LyX-Compiler/issues/1961|#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'' ([[https://github.com/SEOLizer/LyX-Compiler/issues/1677|#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 ===== * **Binärdaten sind nicht nullterminiert.** ''ResFind'' liefert einen ''pchar'', aber die Bytes stammen aus der Datei: enthält sie ein Nullbyte, endet jede Zeichenkettenfunktion dort. Die Länge kommt aus ''ResLen'', nicht aus ''StrLen'' — gemessen: eine Datei mit ''A\0B\0C'' meldet korrekt ''5''. * **Der Name ist frei wählbar** und hat nichts mit dem Dateinamen zu tun. Zwei Ressourcen mit demselben Namen sind nicht sinnvoll; gesucht wird der erste Treffer. * **Fehlt die Datei, bricht die Übersetzung ab**: ''error: @resource: Datei nicht lesbar: ''. Das ist Absicht — eine fehlende Ressource fällt beim Bauen auf, nicht beim Kunden. * **''@resource'' wirkt über Unit-Grenzen.** Eine importierte Unit darf eigene Ressourcen mitbringen; sie landen in derselben Tabelle und sind über ihren Namen erreichbar. **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**. ---- ===== 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'' ([[https://github.com/SEOLizer/LyX-Compiler/issues/1961|#1961]] Stufe 1 und 2), alle Beispiele gegen lyxc 1.2.2D übersetzt und ausgeführt. ===== Ressourcen in einer ''.lyu'' ===== Seit [[https://github.com/SEOLizer/LyX-Compiler/issues/1971|#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 ([[https://github.com/SEOLizer/LyX-Compiler/issues/1968|#1968]]). > **Der Import daraus fehlt noch.** Eine ''.lyu'' trägt die Ressourcen zwar, aber eine importierende Übersetzung übernimmt sie nicht — das hängt an [[https://github.com/SEOLizer/LyX-Compiler/issues/2014|#2014]], solange die ''.lyu'' eine reine Namensliste ist. Offen sind ebenso die IR-Ziele und das LBF-Format.