6. Tip's in Verbindung mit Pointern und PowerBASIC 3.2

English


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

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%
    '************************************************************************


(c) 1995/2007 by Thomas Gohel, All rights und bug's reserved