|
|
|
|
|
Kapitel 10 |
Einleitung
Anforderungen an die Struktur von Libraries
Tips für die Library-Programmierung
Die Prozedur Exported_Symbols
Die Fehlermeldungen des Library Makers
Einleitung
Sie kennen sicher schon die Extension Library, die ja zusammen mit dem Omikron Basic ausgeliefert wird. Dabei handelt
es sich um eine Sammlung von Prozeduren und Funktionen, die so codiert wurden, daß sie in einer einzigen
Zeile Platz finden, von der im Editor aber nur der Anfang angezeigt wird. Der eigentliche Programmcode der Library
ist nicht sichtbar und kann auch nicht verändert werden. Eine Library stellt somit eine Art Befehlserweiterung
für das Omikron Basic dar, entspricht also in etwa den Include-Datein in der Programmiersprache C.
Mit der Funktion 'Library erzeugen' aus dem Programm-Menü können
Sie sich solche Libraries nun auch selbst herstellen.
Was an Prozeduren und Funktionen genau in der Library vorhanden ist, wissen Sie entweder, weil Sie die Library
selber geschrieben haben oder Sie müssen dies der Anleitung zu der Library entnehmen.
Anforderungen an die Struktur von Libraries
Damit aus einem BASIC-Programm eine Library erzeugt werden kann, muß der Quelltext bestimmte Voraussetzungen
erfüllen:
Eine Library darf nur aus Prozeduren und
Funktionen bestehen.
Außerhalb von Prozeduren und Funktionen darf es nur Kommentare und geschweifte Klammern zum Einklappen von
Programmteilen geben. Außerdem ist der Befehl COMPILER erlaubt, wenn danach eines der beiden Steuerwörter
"LIB_MAKER OFF" oder LIB_MAKER ON" folgt.
Die erste Prozedur gibt der Library ihren
Namen. Ein Aufruf dieser Prozedur sollte eine Copyright-Meldung ausgeben. Am besten verwenden Sie dafür den
FORM_ALERT Befehl.
Die Prozedur darf eingerückt sein und es dürfen auch Kommentarzeilen oder Einklappklammern davor stehen.
Der Quelltext muß eine Prozedur mit
dem Namen Exported_Symbols haben. Sinnvoll ist es, sie gleich als zweite in den
Quelltext aufzunehmen. In ihr müssen alle Prozeduren, Funktionen, Variablen, Felder und Labels, die auch von
außerhalb der Library aufrufbar sein sollen, mindestens einmal vorkommen.
Während es bei Prozeduren und Funktionen sinnvoll sein kann, großzügig mit der globalen Verfügbarkeit
zu sein, sollten Sie mit globalen Variablen und Feldern vorsichtig umgehen, je weniger, desto besser. So können
versehentliche "Datenlecks", die später zu schwer nachvollziehbaren Fehlern führen, am einfachsten
vermieden werden.
Labels sollten am besten gar nicht exportiert werden. Falls Sie wirklich meinen, daß dies unumgänglich
ist, müssen sie mit GOTO bzw. GOSUB aufgerufen werden.
Wichtig: Wenn Sie von der Library aus auf Funktionen und Prozeduren außerhalb
der Library zugreifen wollen, müssen diese ebenfalls in der Exported_Symbols
Prozedur auftauchen.
Prozeduren und/oder Funktionen dürfen
nicht verschachtelt sein. Sie dürfen also nicht innerhalb einer Prozedurdefinition eine weitere beginnen.
Strukturbefehle müssen in der richtigen
Reihenfolge erscheinen. Also erst FOR und später NEXT, erst REPEAT, dann UNTIL usw.. Es ist also z.B. nicht
erlaubt, eine Schleife zunächst mit FOR zu beginnen, dann mit GOTO zu einem NEXT zu springen, das sich vor
dem FOR befindet. Aber solche extrem unübersichtlichen Konstruktionen sollte man ohnehin vermeiden.
Strukturen müssen eindeutige Ein-
und Ausgänge haben, also zu jedem FOR genau ein NEXT etc. Diese müssen sich auch in derselben Prozedur
bzw. Funktion befinden. Zusätzliche Ausgänge mit EXIT sind natürlich erlaubt.
IF Konstruktionen müssen ebenfalls
sauber angelegt werden, also bei mehrzeiligem IF muß ein ENDIF vorhanden sein und es muß sich hinter
dem IF befinden.
Für SELECT Strukturen gilt auch entsprechendes,
der Library Maker prüft diese aber nicht. D.h. eine Library mit einer fehlerhaften SELECT Struktur wird ohne
Fehlermeldung übersetzt. Beim Hinzulinken zu Programmen wird diese Library aber zu Fehlern führen, die
dann nur schwer zu finden sind, erst recht für die Anwender der Library, die den Quelltext nicht besitzen.
Nie mit GOTO oder GOSUB von einer Prozedur
in eine andere springen. Wenn die andere Prozedur ansonsten nicht aufgerufen wird, so wird sie auch nicht in das
Compilat übernommen. Der Sprungbefehl mit GOTO bzw. GOSUB führt dann in's Nirwana. Und guter Programmierstil
ist das schon gar nicht.
Alles an Programmcode, was für eine
Prozedur oder Funktion benötigt wird, muß in dieser selbst enthalten sein. In Libraries müssen
deshalb z.B. DATA-Zeilen innerhalb der Prozedur stehen, in der sich auch der READ-Befehl befindet. Alternativ dazu
können DATA-Zeilen auch in einer Pseudo-Prozedur stehen, die von der Prozedur mit dem READ-Befehl durch ein
"IF 0 THEN Pseudoprozedur" scheinbar aufgerufen wird. Von dieser Alternative
wird aber abgeraten!
Hinter einem einzeiligen IF darf keine
Struktur beginnen (z.B. eine Schleife oder eine weitere IF Struktur), die über mehrere Zeilen geht.
Die Verwendung des Befehls MEMORY_BLOCK
ist in Libraries nicht möglich.
Tips für die Library-Programmierung
Vermeiden Sie GOTO und GOSUB. Es gibt nichts,
was sich nicht mit anderen Konstruktionen auch erledigen läßt. In manchen Fällen kann die Verwendung
aber doch sinnvoll sein. Dann müssen Sie als Ziele aber unbedingt Label und keine Zeilennummern verwenden,
da sich die ganze Library ja in einer einzigen Zeile befindet.
Benutzen Sie so wenig wie möglich
globale Variablen. Jede globale Variable ist eine potentielle Fehlerquelle. Die Gefahren werden allerdings dadurch
gemildert, daß alle Variablen, die nicht explizit exportiert werden, librarylokal sind, also von außen
werden abgefragt noch verändert werden können.
Wenn Sie unbedingt globale Variablen exportieren
müssen, dann sollten diese einen aussagekräftigen Namen bekommen. Es sollte also am Namen erkennbar sein,
wozu die Variable dient. Außerdem sollten die Namen so gewählt werden, daß nicht die Gefahr besteht,
daß sie in einem Programmtext, zu dem die Library hinzugeladen wurde, zufällig für einen anderen
Zweck verwendet werden.
Dokumentieren sie alle von Ihrer Library
exportierten globalen Variablen, Prozeduren und Funktionen, damit die Anwender der Library nicht von merkwürdigen
Seiteneffekten überrascht werden, indem sich z.B. in der Library eine exportierte Variable, Prozedur oder
Funktion befindet, die auch im Anwenderprogramm verwendet wird, allerdings dort für andere Zwecke.
Jede Library, die bestimmte Datenstrukturen
voraussetzt, sollte eine Init-Prozedur haben, in der sämtliche globalen Variablen initialisiert und Arrays
angelegt werden und die insgesamt die Library in einen definierten Grundzustand versetzt.
Wenn die notwendigen Datenstrukturen für
eine Library Speicher beanspruchen, sollte die Library auch eine Exit-Prozedur besitzen, in der z.B. belegte Speicher-Blöcke
freigegeben werden und Arrays auf ihre Minimalgröße verkleinert werden.
Beim Erzeugen der Library haben Sie die
Möglichkeit, ein Release-Datum (gegebenenfalls auch die Uhrzeit) und eine Versionsnummer anzugeben. Nutzen
Sie diese Möglichkeiten für eine eindeutige Kennzeichnung Ihrer Library. Die angegebenen Informationen
erscheinen später in der Libraryzeile hinter dem Librarynamen.
Bevor Sie eine Library erzeugen, mit der
Sie länger arbeiten wollen oder die Sie auch veröffentlichen wollen, sollten Sie im Editor die Funktion
'Aufräumen' aus dem Programm-Menü aufrufen. Der Editor löscht
dann alle nicht mehr benötigten Symbole aus dem Quelltext der Library, wodurch die Library kürzer wird.
Der Library Maker überprüft nämlich nicht, ob ein Bezeichner in der Library überhaupt verwendet
wird.
Die Prozedur Exported_Symbols
Die Prozedur Exported_Symbols ist für die erfolgreiche Erzeugung einer Library
unbedingt erforderlich. Alle Symbole (also Prozeduren, Funktionen, Variablen, Arrays und Labels), die nicht in
dieser Prozedur erscheinen, werden bei der Erzeugung der Library zu librarylokalen Symbolen, sind also nur innerhalb
der Library zu erreichen. Eine Funktion kann so also z.B. eine interne Subfunktion aufrufen, die von außen
(also vom BASIC-Programm oder von anderen Libraries aus) überhaupt nicht erreichbar ist. Dadurch ist sichergestellt,
daß bei Verwendung von mehreren Libraries keine ungewollten Überschneidungen entstehen. In zwei verschiedenen
Libraries können also nicht zwei interne Funktionen mit dem gleichen Namen vorkommen, was zu einem Fehler
führen würde. Globale Variablen einer Library, die nicht exportiert werden, sind damit von außerhalb
der Library nicht mehr veränderbar. Eine Fehlerquelle ist damit ausgeschaltet.
Die exportierten Symbole müssen in der Prozedur Exported_Symbols in einer syntaktisch
korrekten Form aufgeführt werden. Damit ist folgendes gemeint:
Variablen und Arrays müssen in Form
einer Zuweisung in der Prozedur stehen. Dabei ist egal, ob sie links oder rechts vom Gleichheitszeichen stehen.
Bei Arrays muß auch die Anzahl der Parameter stimmen.
Funktionen müssen ebenfalls in einer
Zuweisung vorkommen. Das ist nur rechts des Gleichheitszeichens möglich. Auf der linken Seite dieser Zuweisung
muß eine passende Variable stehen. Bei einer String-Funktion also eine String-Variable.
Prozeduren werden ganz normal in die Prozedur
geschrieben. Die Parameteranzahl muß hier natürlich auch korrekt sein.
Labels können durch einen GOSUB oder
GOTO Aufruf in Exported_Symbols eingetragen werden.
Die Prozedur Exported_Symbols wird vom Library Maker zwar ausgewertet, aber nicht
mit in den Librarycode übernommen, sie ist also in der fertigen Library nicht enthalten. Sie darf deshalb
auch nicht aufgerufen werden, was auch überhaupt keinen Sinn hätte. Daraus ergibt sich zugleich, daß
die Parametertypen, die in Exported_Symbols an Funktionen und Prozeduren angehängt
werden, völlig beliebig sind. Nur, was links vom Gleichheitszeichen steht, muß zu dem passen, was rechts
vom Gleichheitszeichen steht. Ansonsten wird die Zeile vom Editor nicht tokenisiert.
Exported_Symbols selber ist eine Prozedur ohne Übergabeparameter. Sie darf
sich auch nicht selber (quasi rekursisv) aufrufen, weil dieser Prozedurname außerhalb der Library nicht benötigt
wird. Die Prozedur Exported_Symbols würde außerdem in keinem Fall in
die Library kommen. Ein Aufruf von außen würde also vom Compiler gar nicht übersetzt werden können.
Wenn innerhalb der Prozedur Exported_Symbols ein LOCAL Befehl steht, werden die
dahinter stehenden Variablen auch lokal behandelt. Diese Variablen sind also librarylokal, obwohl sie innerhalb
der Prozedur vorkommen. Das kann dazu genutzt werden, die Prozedur übersichtlicher zu gestalten, indem man
Void oder Dummy als lokale Variablen von Exported_Symbols
deklariert und überall einsetzt, wo Parameter benötigt werden.
In die Exported_Symbols Prozedur müssen übrigens auf jeden Fall auch alle
importierten Symbole aufgenommen werden. Das sind Prozeduren und Funktionen, die in der Library zwar aufgerufen,
aber in einer anderen Library oder im Programm selbst definiert werden.
Der Library Maker sucht die Exported_Symbols Prozedur übrigens ganz zu Beginn
seines Arbeitsprozesses, indem er das Programm von vorne nach hinten durchgeht. Er findet sie etwas schneller,
wenn sie möglichst weit vorne im Quelltext steht. Da die Position dieser Prozedur für die weitere Übersetzung
keine Rolle mehr spielt, sollte sie sich gleich als zweite Prozedur hinter der namensgebenden Prozedur befinden.
Sie sollte aber nicht die erste Prozedur sein, denn sie wollen Ihre Library ja sicher nicht "Exported_Symbols"
nennen. ;-)
Die Fehlermeldungen des Library Makers
Wärend der Erzeugung einer Library können eine Reihe von Fehlermeldungen auftreten. Diese erscheinen
ähnlich wie beim Compiler in dem aktuellen Übersetzungsfenster. Sofern sie nicht selbsterklärend
sind (z.B. UNTIL ohne REPEAT), werden sie nachfolgend genauer besprochen.
DEF PROC Exported_Symbols ist nicht vorhanden:
Der Library Maker unterscheidet zwischen globalen Prozeduren, Funktionen, Variablen und librarylokalen
Prozeduren, Funktionen, Variablen. Der Vorteil dieser Unterscheidung besteht darin, daß sich gleichnamige
Prozeduren in verschiedenen Libraries, die zu dem gleichen BASIC-Programm hinzugelinkt werden, nicht gegenseitig
stören können.
Damit der Library Maker weiß, welche Prozeduren, Funktionen und Variablen global sein sollen, also auch von
dem BASIC-Programm oder anderen Libraries aufgerufen werden dürfen, müssen alle diese Bezeichner in einer
Prozedur Exported_Symbols deklariert werden. Falls diese Prozedur nicht vorhanden
ist (oder keinen Inhalt hat) wäre die Library von außen gar nicht mehr ansprechbar und darum gibt es
eine Fehlermeldung.
Unerlaubter Befehl außerhalb von PROC/FN:
Eine Library stellt eine Prozedur- und Funktionssammlung dar, die nach Bedarf zum eigentlichen Programm dazugeladen
werden kann. Dabei sollen beim Compilieren nur die Teile in das Compilat übernommen werden, die auch wirklich
benötigt werden. Der Compiler kann nur feststellen, welche Teile einer Library tatsächlich benötigt
werden, wenn diese sauber voneinander getrennt sind. Deshalb darf eine Library nur aus Prozeduren und Funktionen
bestehen. Außerhalb von Prozeduren und Funktionen dürfen sich nur Kommentare und die Klammern zum Einklappen
des Quelltextes befinden sowie der Befehl COMPILER, wenn er die Steuerwörter "LIB_MAKER OFF" oder
"LIB_MAKER ON" (und nur diese) als Parameter hat.
MEMORY_BLOCK nicht erlaubt:
Memory-Blöcke sind in Libraries nicht möglich, weil nicht definiert ist, wie sie zu finden wären.
Sie müssen deshalb entweder im Hauptprogramm dazugeladen werden oder Byte für Byte in DATA's untergebracht
und dann in einer Library-Funktion/Prozedur (z.B. der Init-Prozedur) in einen mit MEMORY angeforderten Speicherblock
übertragen werden.
DEF PROC innerhalb von DEF PROC:
Bevor eine Prozedur/Funktion mit END_PROC/END_FN beendet wurde wird eine neue Prozedur/Funktion mit DEF PROC/FN
begonnen. Wahrscheinlich wurde das END_PROC/END_FN einfach vergessen.
Struktur nicht geschlossen:
Dieser Fehler tritt auf, wenn eine Struktur (FOR, WHILE, REPEAT ...) geöffnet, aber bis zum Ende der jeweiligen
Prozedur nicht wieder geschlossen wurde.
Zu wenig Speicher reserviert:
Der Library Maker benötigt zur Erzeugung des Librarycodes Speicher im Application-Heap des Omikron Basic Editors. Wenn diese Fehlermeldung erscheint, müssen Sie entweder nicht mehr benötigte Fenster schließen oder bei 'Speichereinstellungen ...' im Modus-Menü und gegebenenfalls auch vom Finder aus bei 'Information' im Datei-Menü mehr Speicher reservieren.
|
|
|
Support | Bestellen | Start | Home: http://www.berkhan.de |
|
© 1997-2001 |