|
|
|
|
|
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 |