Bei den meisten Compilersprachen wird ein Programm zunächst
compiliert (d.h. vom Quelltext in den Maschinencode übersetzt) und
dann gelinkt (d.h. mit anderen Programmteilen und
Bibliotheksfunktionen zusammengefügt und als Programmdatei
abgespeichert) bevor es ausgeführt werden kann. Beim
Load-Time-Linking (kurz LTL
) spart man sich den letzten Schritt
auf, bis das Programm ausgeführt werden soll. Erst dann fügt der
sogenannte Loader das Programm zusammen, ohne es jedoch als
Programmdatei abzuspeichern. Der Linkvorgang findet also im
Hauptspeicher, unmittelbar vor der Ausführung des Programms, statt.
Dieser Text beschreibt ein Protokoll, über das eine Shell mit einem Loader, also einem Program, das Load-Time-Linking implementiert, kommunizieren kann. Dieses Protokoll wurde erstmals von der Entwicklungsumgebung Chatwin und dem Oberon-System STJ-Oberon-2 verwendet. Das Protokoll ist aber so gehalten, daß es prinzipiell auch von anderen Shells und Loadern verwendet werden kann.
Die Kommunikation zwischen Shell und Loader geschieht über einen Cookie namens OBNL. Dieser zeigt auf eine Routine, über die die Shell den Loader aufrufen kann. Folglich muß der Cookie vom Loader angelegt werden.
Die Routine, auf die der OBNL-Cookie zeigt, ist wie folgt deklariert:
int cdecl obnload ( OBNCOMM *com );
D.h. daß der Routine auf dem Stack ein Zeiger auf eine Struktur OBNCOMM übergeben wird und daß die Routine einen 16-Bit-Wert im Register D0 zurückliefert.
Die Struktur OBNCOMM hat folgenden Aufbau:
typedef struct _obncomm { int type; void *ptr; int chr; void *env; } OBNCOMM;
Das Feld `type' enthält jeweils eine Nachrichtennummer. In Abhängigkeit von dieser Nummer sind dann die anderen Einträge der Struktur belegt.
int
ist eine vorzeichenbehaftete 16-Bit-Zahl,
void *
ist ein Zeiger auf irgendwas
, d.h. es ist
zunächst nicht genauer spezifiziert, auf welche Art von Daten der
Zeiger zeigt.
Die Shell kann die folgenden Nachrichten an den Loader senden:
Nachricht Nummer CL_INIT 0x6500 CL_COMMAND 0x6501 CL_TIME 0x6502
Nachrichten von der Shell an den Loader beginnen immer mit CL_.
Bitte beachten: Es handelt sich hierbei nicht um AES-Nachrichten! Die Kommunikation geschieht über die Routine, auf die der OBNL-Cookie zeigt.
Über die Nachricht CL_INIT teilt die Shell dem Loader mit, daß sie das LTL-Protokoll unterstützt. Gleichzeitig übergibt sie dem Loader die Adresse einer Funktion, über die der Loader bestimmte Aktionen in der Shell auslösen kann.
Die Funktion in der Shell hat die gleichen Parameter wie die Funktion, auf die der OBNL-Cookie zeigt:
int cdecl obnshell ( OBNCOMM *com );
Belegung der OBNCOMM-Struktur:
type | CL_INIT
|
ptr | Adresse der Funktion in der Shell
|
chr | undefiniert
|
env | undefiniert
|
Die Shell soll ein Kommando ausführen, das ein Load-Time-Linking erfordert. Sie reicht daraufhin das komplette Kommando an den Loader weiter.
Belegung der OBNCOMM-Struktur:
type | CL_COMMAND
|
ptr | Zeiger auf einen nullterminierten String, der das gesamte
eingegebene Kommando (also inkl. Parameter) enthält.
|
chr | undefiniert
|
env | Zeiger auf das Environment.
|
Wenn längere Zeit keine Benutzereingaben vorliegen und die Shell auch sonst nichts zu tun hat, so kann sie den Loader benachrichtigen, damit dieser evtl. Arbeiten im Hintergrund erledigen kann.
Belegung der OBNCOMM-Struktur:
type | CL_TIME
|
ptr | undefiniert
|
chr | undefiniert
|
env | undefiniert
|
Der Loader kann folgende Nachrichten an die Shell schicken:
Nachricht Nummer LC_WRCHAR 0x6503 LC_WRSTR 0x6504 LC_OUTBUF 0x6505 LC_CLOSEWIN 0x6506 LC_OPENWIN 0x6507
Nachrichten von dem Loader an die Shell beginnen immer mit LC_.
Bitte beachten: Es handelt sich hierbei nicht um AES-Nachrichten! Die Kommunikation geschieht über die Routine, die die Shell dem Loader bei CL_INIT mitgeteilt hat.
Der Loader schickt der Shell ein Zeichen, das in der Console ausgegeben werden soll.
Belegung der OBNCOMM-Struktur:
type | LC_WRCHAR
|
ptr | undefiniert
|
chr | das auszugebende Zeichen
|
env | undefiniert
|
Der Loader schickt der Shell einen nullterminierten String, der in der Console ausgegeben werden soll.
Belegung der OBNCOMM-Struktur:
type | LC_WRSTR
|
ptr | Zeiger auf den auszugebenden String
|
chr | undefiniert
|
env | undefiniert
|
Der Loader weist die Shell an, evtl. noch gepufferte Zeichen jetzt in der Console auszugeben.
Belegung der OBNCOMM-Struktur:
type | LC_OUTBUF
|
ptr | undefiniert
|
chr | undefiniert
|
env | undefiniert
|
Der Loader weist die Shell an, alle evtl. gerade offenen Fenster zu schließen. Dieser Aufruf wird beim Start eines GEM-Moduls unter SingleTOS benötigt.
Belegung der OBNCOMM-Struktur:
type | LC_CLOSEWIN
|
ptr | undefiniert
|
chr | undefiniert
|
env | undefiniert
|
Der Loader weist die Shell an, alle zuvor bei LC_CLOSEWIN geschlossenen Fenster wieder zu öffnen.
Belegung der OBNCOMM-Struktur:
type | LC_OPENWIN
|
ptr | undefiniert
|
chr | undefiniert
|
env | undefiniert
|
Als Beispiel soll hier kurz aufgeführt werden, wie Chatwin (Shell) und STJ-Oberon-2 (Loader) das LTL-Protokoll implementieren:
Der Oberon-Loader richtet den OBNL-Cookie ein und
startet dann Chatwin nach.
Chatwin erkennt am Vorhandensein des Cookies, daß LTL
gewünscht ist und meldet sich mit dem Aufruf CL_INIT beim
Loader an. Dabei übergibt Chatwin einen Zeiger auf eine Funktion,
über die der Loader wiederum Aktionen in Chatwin auslösen kann.
Wann immer Chatwin nun angewiesen wird, eine Datei mit der
Extension *.OBJ zu starten, übergibt er diese Datei und die
evtl. übergebenen Parameter mittels der Nachricht CL_COMMAND
an den Loader.
Der Loader muß nun das Programm starten. Handelt es sich um ein
TOS-Programm, so kann er die Ausgaben dieses Programms über die
Nachrichten LC_WRCHAR und LC_WRSTR in das Console-Fenster
von Chatwin ausgeben lassen. Handelt es sich um ein GEM-Programm,
so kann der Loader Chatwin unter SingleTOS dazu auffordern, alle seine
Fenster zu schließen (Nachricht LC_CLOSEWIN), bevor das
Programm gestartet wird.
Anmerkung: Chatwin erkennt anhand der Extension, ob für
eine Datei ein Load-Time-Linking durchzuführen ist. In älteren
Versionen ist die Extension *.OBJ fest vorgegeben, ab Chatwin
3.04 kann die Extension in der Environmentvariablen $LTLEXT
angegeben werden. Dadurch ist Chatwin auch für andere Sprachen
gerüstet, die nicht *.OBJ als Extension für die Objektfiles
verwenden.
Wenn längere Zeit keine Benutzereingaben und auch keine
sonstigen Aufgaben anliegen, gibt Chatwin Zeit an den Loader ab, indem
er die Nachricht CL_TIME schickt. Der Loader kann dadurch
bestimmte Aufgaben im Hintergrund erledigen.
Für das Programmende gibt es kein spezielles Protokoll: Wenn
Chatwin beendet wird, beendet sich auch der Loader.