9. Weitere Libraries für Omikron Basic 11. Der Source Code Debugger

 

Kapitel 10

Der Library Maker



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.


9. Weitere Libraries für Omikron Basic 11. Der Source Code Debugger

Support | Bestellen | Start | Home: http://www.berkhan.de


© 1997-2001 Berkhan-Software