6. Tip's in Verbindung mit Pointern und PowerBASIC 3.2
Kürzübersicht:
6.1. Allgemeines über Pointer
6.2. Was sind Pointer und was können sie leisten?
6.3. PowerBASIC-Pointer und dynamische Strings
6.4. PowerBASIC-Pointer und feste Strings
6.5. PowerBASIC-Pointer und Flex Strings
6.6. PowerBASIC-Pointer und TYPE Strukturen
6.7. Demonstrations-Source
6.1. Allgemeines über PowerBASIC-Pointer
Pointer in Verbindung BASIC haben bereits zahlreiche Diskussionen
entfacht, die dynamische Speicherverwaltung von PowerBASIC wird hierbei
immer als 'Geburtsfehler' ins Feld geführt.
Das sich dieser elementare Vorteil der BASIC-Programmiersprache auch
ohne Probleme beim Einsatz von Pointern ausspielen läßt, soll Ihnen
dieser Abschnitt erläutern, denn der Einsatz von Pointern in PowerBASIC
ist mit keinerlei Einschränkungen verbunden!
Allerdings sollten Sie für das Lesen folgender Artikel bereits Wissen
über die interne Wirkungsweise von BASIC und auch DOS haben.
6.2. Was sind Pointer und was können sie leisten?
Pointer (auch Zeiger genannt) bieten die Möglichkeit, Datenstrukturen
an einer beliebigen Stelle des DOS-Speichers zu interpretieren. Dazu
müssen Sie dem Pointer nur eine beliebige Adresse übergeben.
Pointer dienen vor allem dazu Speicherbereiche zu nutzen, welche
außerhalb der dynamischen Speicherverwaltung von PowerBASIC liegen. Sie
können mit Pointern z.B. direkt Strukturen interpretieren, auf die von
DOS-Funktionen Zeiger zurückgeliefert werden, wie z.B.:
- Directory Table Area
- Drive Parameter Block
- DOS Info Block
- PSP
- Environment Block
- und und und ...
Das bisher notwendige Umkopieren mit DEF SEG/POKE/PEEK entfällt ab sofort
und auch das leidige DEF SEG = PEEKI(...) sollten Sie in einem solchem
Falle sofort vergessen.
6.3. PowerBASIC-Pointer und dynamische Strings
String-Pointer auf feste Strings müssen in PowerBASIC wie folgt definiert
werden:
DIM Pointer AS STRING PTR
Der Pointer selber ist wie folgt zu initialisieren:
Pointer = VARPTR32(Demo1$)
Beispiel:
'***************************************************************
'
' Demo zum korrekten Umgang mit Pointern und dynamische Strings
'
'***************************************************************
DIM Pointer1 AS STRING PTR ' String Pointer für dynamische
' Strings definieren
Pointer1 = VARPTR32(Demo1$) ' Zeiger auf Stringhandle holen
CLS
PRINT "Adresse: Demo1$: Pointer1:"
Demo1$ = "123456"
PRINT HEX$(VARPTR32(Demo1$)), Demo1$, @Pointer1
Demo1$ = "654321"
PRINT HEX$(VARPTR32(Demo1$)), Demo1$, @Pointer1
Demo1$ = "!Test!"
PRINT HEX$(VARPTR32(Demo1$)), Demo1$, @Pointer1
6.4. PowerBASIC-Pointer und feste Strings
String-Pointer auf feste Strings müssen in PowerBASIC wie folgt definiert
werden:
DIM Demo AS STRING * 6
DIM Pointer AS STRING PTR * 6
Der Pointer selber ist wie folgt zu initialisieren:
Pointer = VARPTR32(Demo$)
Beispiel:
'***************************************************************
'
' Demo zum korrekten Umgang mit Pointern und festen Strings
'
'***************************************************************
DIM Demo2 AS STRING * 6 ' String mit konstanter Länge
' definieren!
DIM Pointer2 AS STRING PTR * 6
' String Pointer definieren
Pointer2 = VARPTR32(Demo2$) ' Zeiger auf String holen
PRINT
PRINT
PRINT "Adresse: Demo2$: Pointer2:"
Demo2$ = "123456"
PRINT HEX$(VARPTR32(Demo2$)), Demo2$, @Pointer2
Demo2$ = "654321"
PRINT HEX$(VARPTR32(Demo2$)), Demo2$, @Pointer2
Demo2$ = "!Test!"
PRINT HEX$(VARPTR32(Demo2$)), Demo2$, @Pointer2
6.5. PowerBASIC-Pointer und FLEX-Strings
Pointer auf FLEX-Strings müssen in PowerBASIC wie folgt definiert
werden:
DIM Demo AS FLEX
DIM Pointer AS FLEX PTR
Der Pointer selber ist wie folgt zu initialisieren:
Pointer1 = VARPTR32(Demo1$)
Um mit FLEX-Strings korrekt arbeiten zu können, müssen diese vor dem
Erstellen des Pointers mit MAP gebildet werden!
Beispiel:
'***************************************************************
'
' Demo zum korrekten Umgang mit Pointern und FLEX Strings
'
'***************************************************************
DIM Demo3 AS FLEX ' String als FLEX definieren!
DIM Pointer AS FLEX PTR
MAP Demo3$$ * 10 '
FLEXCHR$ = "."
Pointer = VARPTR32(Demo3$$) ' Zeiger auf FLEX$-Handle holen
PRINT
PRINT
PRINT "Adresse: Demo3$$: Pointer:"
Demo3$$ = "123456"
PRINT HEX$(VARPTR32(Demo3$$)), Demo3$$, @Pointer
Demo3$$ = "654321"
PRINT HEX$(VARPTR32(Demo3$$)), Demo3$$, @Pointer
Demo3$$ = "!Test!"
PRINT HEX$(VARPTR32(Demo3$$)), Demo3$$, @Pointer
6.6. PowerBASIC-Pointer und TYPE Strukturen
Pointer auf TYPE Strukturen müssen in PowerBASIC wie folgt definiert
werden:
TYPE Demo4_Struc ' TYPE definieren
Demo5 AS BYTE
Demo6 AS BYTE
END TYPE
Der Pointer selber ist wie folgt zu initialisieren:
DIM TypeDemo AS SHARED Demo4_Struc PTR
Ein Beispiel zu Pointern und TYPE Strukturen finden sie eine Source
im folgenden Abschnitt.
6.7. Demonstrations-Source
'************************************************************************
'
' Zugriff auf den Videoram über Pointer in PowerBASIC 3.2
'
' (c) Thomas Gohel
'
' Eine kleine Demonstration, das Pointer wirklich nichts (!!) mit der
' internen Speicherverwaltung zu tun haben und der erfolgreiche Einsatz
' von Pointern sehr gute interne Kenntnisse von PowerBASIC vorraussetzt.
'
' In diesem Demo wird der Videoram als Speicher mißbraucht und gezeigt,
' wie PRINT-Ausgaben den Inhalt der beiden Pointer VIDEORAM und ZEICHEN
' modifizieren.
'
' Als sinnvolle Erweiterung könnte man diese Routine zum schnellen
' Sichern und Restaurieren des kompletten Videorams nutzen:
'
' @Videoram.Page2 = @Videoram.Page1
'
' würde den kompletten Inhalt der ersten Page in die zweite Seite retten
' um später wieder restauriert werden zu können
'
'************************************************************************
TYPE Zeichen_Struc ' Aufbau eines einzelnen Zeichens
Wert AS BYTE
Farbe AS BYTE
END TYPE
TYPE Screen_Struc ' Aufbau der Seiten im Videoram
Page1 AS STRING * 4096 ' Seite 1
Page2 AS STRING * 4096 ' Seite 2
Page3 AS STRING * 4096 ' Seite 3
Page4 AS STRING * 4096 ' Seite 4
END TYPE
DIM Zeichen AS SHARED Zeichen_Struc PTR
DIM Videoram AS SHARED Screen_Struc PTR ' TYPE-Strukturen erzeugen
Videoram = pbvScrnBuff ' Type-Struktur auf den Anfang
' des aktuellen Video-Ram
' schieben,
' PowerBASIC nutzt und verwaltet
' den Videoram ab sofort als
' festen Stringspeicher! :-)))
Zeichen = pbvScrnBuff ' TYPE-Struktur soll gleichen
' Speicherbereich wie PRINT und
' VIDEORAM nutzen
SCREEN 0 ' Screen-Mode setzen
CLS ' alles löschen
PRINT "Dies ist ein Test" ' normales PRINT auf den
' Bildschirm
A$=INPUT$(1)
PRINT LEFT$(@Videoram.Page1,34) ' Anzeigen der PRINT-Befehl
' automatisch auch unsere
' Struktur gefüllt wird
A$=INPUT$(1)
@Videoram.Page2 = @Videoram.Page1 ' Videoram in Page 2 retten
@Zeichen.Wert = 76 ' Jetzt wird die Zeichen-
' Struktur mit einem Wert
@Zeichen.Farbe = 14 ' gefüllt. Hierbei erfolgt
' gleichzeitig die Ausgabe
' auf den Bildschirm und das
' aktualiseren von der Video-
' RAM-Struktur
PRINT LEFT$(@Videoram.Page1,34)
A$=INPUT$(1)
@Videoram.Page1 = @Videoram.Page2 ' Videoram von Page 1
' restaurieren
Pointer_Speed_Test:
PRINT STRING$(25*80,178); ' Bildschirm füllen
LOCATE 1, 9
COLOR 11, 1
PRINT " -= STRING-Manipulation innerhalb des";
PRINT " Bildschirmspeichers! =- "
@Videoram.Page2 = @Videoram.Page1
COLOR 14, 1
LOCATE 8,20: PRINT "ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"
FOR i% = 9 TO 18
LOCATE i%, 20
PRINT "³ ³"
NEXT i%
LOCATE 10, 22: PRINT "Bildschirmspeicher wird als STRING"
LOCATE 11, 22: PRINT "verwaltet!"
LOCATE 13, 22: PRINT " -= Ein Demo zur PowerBASIC-FAQ =- "
LOCATE 19, 20
PRINT "ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"
@Videoram.Page3 = @Videoram.Page1
FOR i% = 1 to 1000
@Videoram.Page1 = @Videoram.Page2
@Videoram.Page1 = @Videoram.Page3
NEXT i%
FOR i% = 1 TO 10
FOR Durchlauf% = 1 TO 256
Zeichen = pbvScrnBuff
FOR Offset% = 1 TO 2048
IF @Zeichen.Wert > 32 THEN
DECR @Zeichen.Wert
END IF
Zeichen = Zeichen + 2
NEXT Offset%
NEXT Druchlauf%
@Videoram.Page1 = @Videoram.Page3
NEXT i%
'************************************************************************