•  Back 
  •  Shared Libraries 
  •  Index 
  •  Tree View 
  •  Cross references 
  •  Help page 
  •  Show info about hypertext 
  •  View a new file 
Topic       : TOS - das Betriebssystem
Author      : 
Version     : tos.hyp (5. März 2013)
Subject     : Programmieren/Atari
Nodes       : 3001
Index Size  : 93602
HCP-Version : 5
Compiled on : Atari
@charset    : atarist
@lang       : 
@default    : Titel
@help       : 
@options    : +g -i -s +x +zz -t4
@width      : 70
View Ref-File11.23.4  Wie schreibe ich eine Shared Libraries?                   TOS

Auch dazu gibt es eine Beispielbibliothek SLB_DEMO, die alle 
notwendigen Elemente und Beschreibungen enthält. Am besten, man 
kopiert SLB_DEMO.C, LIBHEAD.S und SLB_DEMO.PRJ und modifiziert die 
Dateien entsprechend. Es muß dringend darauf geachtet werden, daß Bit 
3 der Flags im Programmheader einer Bibliothek gesetzt ist, dazu kann 
man PH_BIT3.TTP verwenden.

LIBHEAD ist der Header für eine Shared Library. Der Zeiger auf die 
Funktionsnamen kann entfallen, ansonsten zeigt er auf eine Tabelle von 
Zeigern mit den Namen der Bibliotheksfunktionen. Die Anzahl der 
Funktionen muß korrekt festgelegt werden, ebenso die Tabelle der 
Funktionen und der Bibliotheksname, welcher mit dem Dateinamen 
identisch ist. Beim Hinzufügen von Funktionen muß darauf geachtet 
werden, die Funktionsanzahl entsprechend anzupassen und ggf. die 
Versionsnummer zu erhöhen.

Bei öffentlich zugänglichen Shared Libraries ist sicherzustellen, daß 
dokumentierte Funktionsaufrufe nie geändert werden! Entweder sind neue 
Parameter zu ergänzen (die aufgerufene Funktion kann die Anzahl der 
tatsächlich übergebenen Parameter abfragen), oder es ist eine neue 
Funktionsnummer zu verwenden.

Für die Funktionszeiger sind auch Nullzeiger zulässig, sie geben beim 
Aufruf der Funktion ein EINVFN.

Folgende Funktionen zur (De-) Initialisierung sind obligatorisch:

slb_init()/slb_exit()

Werden beim Laden bzw. Entfernen der Bibliothek aufgerufen, und zwar 
im Supervisor-Modus und im Kontext (Prozeß) der Bibliothek. 
Typischerweise lädt slb_init() eine Konfigurationsdatei, alloziert 
globalen Speicher für die Bibliothek und öffnet eine virtuelle VDI- 
Workstation. slb_exit() schreibt die Konfigurationsdatei zurück, gibt 
den Speicher wieder frei und schließt die VDI-Workstation.

Falls slb_init() eine Datei öffnet, darf auf das Handle erst wieder 
bei slb_exit() zugegriffen werden, da alle anderen Aufrufe der 
Bibliothek im Kontext des Aufrufers ablaufen.

Ab MagiC 6 erhält die Bibliothek in der Kommandozeilen-Struktur der 
Basepage eine normale 'C'-Zeichenkette übergeben, welche den 
vollständigen Pfad der SharedLibrary enthält. Falls die SharedLibrary 
Konfigurations- oder RSC-Dateien laden muß, kann der Pfad extrahiert 
und der Dateiname der Konfigurationsdatei entsprechend 
zusammengebastelt werden.

Falls slb_init() z.B. aufgrund eines Busfehlers beendet wird, erhält 
der Aufrufer EXCPT als Ergebnis des Slbopen()-Aufrufs. Um die 
unplanmäßige Terminierung der Bibliothek abzufangen, installiert der 
Kernel vor Aufruf von slb_init()/exit() einen etv_term-Handler für die 
Bibliothek.

slb_open()/slb_close()

Werden beim Öffnen bzw. Schließen der Bibliothek aufgerufen. Wenn die 
Bibliothek nur einmal geöffnet wird, ist die Reihenfolge:

  slb_init()
  slb_open()
  slb_close()
  slb_exit()

Im Gegensatz zu slb_init()/slb_exit() laufen slb_open()/slb_close() im 
Kontext des Aufrufers und im Usermodus mit dem Userstack des Aufrufers 
ab, auch dann, wenn der Slbopen()-Aufruf im Supervisor-Modus erfolgt 
ist.

Die Bibliothek kann auch bei slb_open Speicher allozieren, dieser 
gehört jedoch dem Aufrufer und sollte bei slb_close() wieder 
freigegeben werden. Um die Zuordnung von alloziertem Speicher zum 
Aufrufer zu ermöglichen, wird der Bibliothek bei slb_open(), 
slb_close() und bei jedem Funktionsaufruf der aktuelle Prozeß- 
Deskriptor mit übergeben.

Achtung: Die Übergabe des PD an slb_open() und slb_close() geht 
aufgrund eines Bugs in 5.20 erst ab MagiC 6.

Der Kernel stellt sicher, daß die open/close Aufrufe korrekt 
geschachtelt sind, d.h. ein Prozeß kann eine Bibliothek nicht mehrmals 
öffnen.

Funktionen

Funktionen sind nicht obligatorisch, so kann eine Bibliothek auch 
Systemaufrufe über AES oder DOS einhängen, die nach Beendigung wieder 
entfernt werden, i.a. werden jedoch Funktionen zur Verfügung gestellt.

Eine Funktion wird mit folgenden Parametern auf dem Stack aufgerufen:

 PD *pd       Prozeß-Deskriptor des Aufrufers, korrespondiert mit dem 
              zugehörigen slb_open()/close()
 LONG fn      Funktionsnummer. Praktisch, wenn mehrere Funktionen 
              zusammengelegt sind (identische Funktionszeiger in 
              LIBHEAD)
 WORD nargs   Anzahl der folgenden Argumente, in WORDs. Hat eine 
              Funktion eine variable Anzahl von Parametern, kann die 
              tatsächliche Anzahl ermittelt werden. Sehr praktisch bei 
              Erweiterungen, ohne neue Funktionen einzubauen. 
              Beispiel: Erwartet eine Funktion immer einen Zeiger, 
              optional aber noch ein WORD, erhält sie entweder 2 oder 
              3 als <nargs>.
 ...          die übrigen Parameter

Die Funktionen werden im Kontext des Aufrufers und mit dessen Stack 
ausgeführt. Da dieser Aufruf i.a. im User-Modus erfolgt, wird das 
Multitasking auch bei längeren Aktionen nicht unterbrochen. Das 
Funktions-Ergebnis kann je nach Funktion LONG, WORD, void usw. sein.

Eine Funktion darf die Register d0-d2 und a0-a1 ändern, alle anderen 
Register müssen ggf. gerettet werden. Insbesondere darf Register a2 
nicht verändert werden, damit Routinen von PureC aus aufgerufen werden 
können.