Results 1 to 4 of 4

Thread: Pointer, Buffer, Pchar en conversie hiervan.

  1. #1
    5th member of nldelphi
    Join Date
    Mar 2001
    Location
    Alkmaar
    Posts
    2,127

    Lightbulb Pointer, Buffer, Pchar en conversie hiervan.

    Hoi Heren, kan iemand mischien (als die zin heeft en tijd.) mischien is een stukje uitleg over een Pointer, Buffer, Pchar kunnen geven.
    Dit is voormij een fenomeen waar ik totaal niets van weet en snap.
    Bij voorkeur natuurlijk dan met wat voorbeeldjes.
    En wat de conversie's betreft: deze bovenstaande naar strings etc converteren en vica versa uiteraard.

    Dus als iemand zin heeft? leef je uit zou ik zeggen.

    Groet.
    RLD

  2. #2
    Senior Member McTinus's Avatar
    Join Date
    May 2001
    Location
    Hoek van Holland
    Posts
    389
    Dag Richard,

    Delphi kent eigenlijk twee soorten strings: Pascal strings en PChar. PChar wordt door de buitenwereld veelvuldig gebruikt (in api's, DLL's etc.). Een string is niets anders dan een aantal characters aan elkaar geregen, daardoor het woord string. Een pascal string verschilt op een klein punt met PChar. Een PChar is een string die eindigd met het null karakter (ASCII 0). Een pascal string begint met de lengte van de string en het laatste karakter is gewoon de laatste karakter van de string. Dus als je een pascal string wilt converteren naar een PChar dan kan je hem gewoon typecasten met: PChar(pascal_string). Even een voorbeeldje:

    procedure TForm1.Button1Click(Sender: TObject);
    var
    s1: String;
    s2: PChar;
    begin
    s1 := 'McTinus';
    s2 := 'McTinus';

    ShowMessage(s1);
    ShowMessage(s2);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    s2: PChar;
    begin
    s2 := 'McTinus';

    while s2^ <> #0 do {#0 = ASCII 0}
    begin
    ShowMessage(s2^);
    Inc(s2);
    end;
    end;

    In het voorbeeldje van hierboven wordt gebruik gemaakt van een pointer ^. Pointers is een nogal uitgebreid verhaal. Mischien kan iemand anders dat uitleggen?

    Ik ga nu maar eens slapen,

    Groeten

  3. #3
    Goed maar eens proberen om dit uit te leggen. Te beginnen met pointers. Een pointer is een variabele waarin geheugen adressen worden opgeslagen. Dit zijn meestal niet zomaar adressen maar adressen van variabelen, records, objecten en functies of procedures. Pointers worden veelal gebruikt wanneer geheugen dynamisch moet worden gealloceerd. Wanneer je in Delphi begint met programmeren zul je ook veel pointers gebruiken, hoewel dit niet altijd duidelijk is, een voorbeeld:

    var
    Label: TLabel;
    begin
    Label := TLabel.Create(nil);
    Label.Destroy;
    Label := nil;
    end;

    In het bovenstaande stukje wordt gebruik gemaakt van een pointer, namelijk label. In de variabele label worden het adres van het label object dat we aanmaken opgeslagen.

    Ook zien we in het bovenstaande voorbeeld de term nil. Deze term wordt gebruikt om aan te geven dat er geen adres is. Naast pointers naar objecten kunnen we ook pointers hebben naar bijvoorbeeld integers.

    var
    pI: ^Integer;
    K: Integer;
    begin
    K := 10;
    PI := @K;
    PI^ := 15;
    K := K + 1;
    end;

    Goed in het bovenstaande voorbeeld zien we een hoop gegoochel, wat gebeurd er nu eigenlijk:

    1) Er zijn 2 variabelen: K een integer en pI een pointer naar een Integer.
    2) K word gelijk gesteld aan 10
    3) pI wordt gevuld met het adres van K
    4) Het stukje geheugen waar pI naar wijst wordt gelijkgesteld aan 15
    5) K wordt met 1 opgehoogd.

    Wat is nu de uiteindelijke waarde van K??? Het antwoord is 16. Dit komt omdat we bij stap 4 eigenlijk K gelijkgesteld hebben aan 15. We hebben namelijk de inhoud van adres pI gelijkgesteld aan 15 en dit was het adres van K.

    Eerder vertelde ik al dat pointers voornamelijk worden gebruikt voor het dynamisch alloceren van geheugen. Dit heeft echter alleen nut wanneer de pointers moeten wijzen naar datatypen die groters zijn dat de hoeveelheid bytes van een adres. Dit komt omdat we het benodigde geheugen niet alleen moeten reserveren maar ook weer moeten vrijgeven, dus moeten we voor ieder stukje dat we reserveren een variabele hebben waarin het adres staat.

    Het reserveren van een stukje geheugen kan met het commando new. Het vrijgeven gebeurd met het commando dispose.

    var
    pI1,pI2,pI3: PIntegeger;
    begin
    // Reserveer geheugen voor pI1
    new(pI1);
    // Reseveer geheugen voor pI2
    new(pI2)

    pI3 := pI1;

    pI1^ := 5;
    pI2^ := 6;

    // Geef geheugen weer vrij
    Dispose(pI1);
    Dispose(pI2);
    end;

    In het bovenstaande voorbeeld word voor twee nieuwe integers geheugen gereserveerd. pI3 krijgt simpel weg het adres van pI1. Daarna worden er waarden geplaatst op de gereserveerde plekken. Als laatste wordt het geheugen weer vrijgegeven.

    Omdat men zelf verantwoordelijk is voor het alloceren en dealloceren van geheugen wordt het werken met pointers als lastig ervaren. Het vergeten vrij te gegeven van gereserveerd geheugen kan fataal zijn voor processen die continue moeten blijven draaien, de applicatie gaat steeds meer en meer geheugen in beslag nemen, waardoor de computer steeds trager wordt en uiteindelijk zal crashen.

    Ook het vergeten te alloceren van geheugen of het werken met pointers die nog naar een adres wijzen dat al is vrijgegeven resulteerd vaak in een Access violation. Met een beetje geluk krijg je in je code deze access violation consequent, die zijn makkelijk met de debugger op te sporen en op te lossen. Gebeurd het niet consequent maar onregelmatig eens in de zoveel tijd, dan zul je hard moeten zoeken om die bug er uit te krijgen.

    Nu verder met PChars. PChars worden ook wel Null-terminated strings genoemd. Dit wil zeggen dat je een op een volgende reeks van karakters hebt waarvan het einde bepaald wordt door het karakter NULL.

    In de PChar variabele zelf wordt het adres van het eerste karakter gegeven. Het werken met PChars is veel minder prettig dan met de standaard Delphi strings vooral omdat je het alloceren en dealloceren van het geheugen in de gaten moet houden.

    Toen Delphi nog niet bestond en we nog gewoon Pascal deden had een string een maximale lengte van 255 karakters. De lengte van een string was ook van te voren bepaald. Op de Nulde plaats van een string was de lengte van de string opgeslagen(
    In Delphi is dit niet meer het geval omdat we strings langen dan 255 karakters kunnen hebben maar het is wel de reden dat het eerste karakter van een string begint bij 1 ipv 0).

    Als je zo'n string definieerd werd het geheugen voor alle karakters ook direct gereserveerd. In oude pascal programma's zie je dan ook vaak dat duidelijk wordt aan gegeven wat de maximale lengte van een string kon zijn, deed je dit niet dan werden er rustig 256 bytes gereserveerd voor een string en dat is best veel als je maar 640 KB heb.

    Toen Delphi kwam is dit gewijzigd. Binnen Delphi kan gebruik gemaakt worden van strings met grotere lengte dan 255 karakters, dit omdat delphi intern de strings vertaald naar een PChar. De lengte hangt dan ook af van het aantal werkelijke karakters in de string. Er wordt niet meer geheugen gereserveerd dan het aantal karakters + 1(het null karakter).

    Het voordeel van strings boven PChars is dat je bij strings geen rekening hoeft te houden met het reserveren en vrijgegeven van het geheugen, dit doet Delphi voor je. Echter de windows api is geschreven in C en maakt daarom gebruik van PChars en om deze functies te kunnen gebruiken moeten we de Delphi string dus type casten naar een PChar.

    Een buffer is gewoon niet veel meer dan een stukje gereserveerd geheugen. Een buffer als datatype bestaat niet maar een PChar of array van bytes kunnen wel dienen als buffer.

    Ik hoop dat dit allemaal duidelijk is een je wat meer helderheid heeft verschaft, zo niet dan hoor ik het graag, pointers is nu eenmaal een erg lastig onderwerp en ook lastig om over te vertellen zonder een echt gerichte vragen. Mocht je nog bepaalde vragen hebben, zo niet nog meer stel ze gerust.

    Marcel Vroone

  4. #4
    Helaas duurde het tikken wat lang en zijn er wat overlappende stukken maar dat moet geen probleem zijn denk ik.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Replies: 3
    Last Post: 20-Dec-04, 15:41
  2. PChar naar String Conversie
    By eagle00789 in forum Algemeen
    Replies: 19
    Last Post: 05-Jul-04, 11:34
  3. Pointer probleem???
    By Doki in forum Algemeen
    Replies: 11
    Last Post: 27-Feb-04, 17:19
  4. ras statistieken
    By Delphifreak in forum WebDelphi
    Replies: 25
    Last Post: 06-Mar-03, 22:19

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •