[Delphi] Pointer -> Boolean typecast probleem

Pagina: 1
Acties:

  • dr snuggles
  • Registratie: September 2000
  • Niet online
Ik heb een probleem met het typecasten van een pointer in een object. Zie deze simpele code:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
    var
        MyTreeNode      : TTreeNode;
        geldig          : Boolean;
        waar            : Boolean
    begin
        waar            := true;
        MyTreeNode.Data = @waar;
        //Data is een pointer.
        geldig          := boolean(MyTreeNode.Data);

        if (geldig = true) then
            //Dit gebeurt helaas nooit.
    end;

Dit vindt de Delphi Watch:
Delphi:
1
2
3
waar              = true
geldig            = true
(geldig = true)   = false


Wat ik denk dat het probleem is: Delphi vergelijkt stiekem het adres van geldig met true. Als de pointer niet in een object zou zitten, dan zou er een extra ^ bij moeten komen. Maar helaas, de pointer zit nu eenmaal in een object. Als ik toch de ^ achter Data erbij stop, dan wordt het resultaat nil. Logisch, want objecten zijn zelf al pointers. Achter een object hoeft nooit een ^, want deze staat er al automatisch.
Delphi:
1
2
geldig          := boolean(MyTreeNode.Data^);
//Dit resulteert in een error, want de rechterkant van de expressie is nil.


Hoe zorg ik ervoor dat (geldig = true) als true wordt herkend en het if statement dus wordt uitgevoerd :?

[ Voor 21% gewijzigd door dr snuggles op 30-07-2006 14:37 ]


  • Hermarcel
  • Registratie: April 2003
  • Niet online
Ik heb geen ervaring met Delphi, maar

Data is geen pointer (alleen een definitie), MyTreeNode.Data is een pointer. Dus (vanuit mijn C kennis):

geldig := boolean(MyTreeNode.Data^);
of anders
geldig := boolean((MyTreeNode.Data)^);

  • dr snuggles
  • Registratie: September 2000
  • Niet online
Ik volg je logica, aangezien ik ook C gewend ben maar MyTreeNode.Data is echt een pointer volgens de Delphi help.

Overgens heb ik de oplossing al gevonden. Na uren prutsen weet ik de oplossing 3 min na het posten op GoT. Nouwja, ik ben weer blij :).

De oplossing:
Delphi:
1
2
MyTreeNode.Data = pointer(waar);
//Dus NIET @(waar).

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 23-12-2025

_Thanatos_

Ja, en kaal

Je kunt @waar nooit safe in die Data property dumpen, omdat als de waar-variabele out of scope raakt, is de waarde van dat geheugenadres (de pointer) niet meer voorspelbaar. In een volgende functie kan het overschreven worden door een nieuwe variabele te declareren. Het is smerig en wordt volgens mij als unsafe code gezien, maar dit zou moeten werken:
Delphi:
1
2
3
4
5
waar := true; 
MyTreeNode.Data = Pointer(Integer(waar));
geldig := Boolean(Integer(MyTreeNode.Data));

if geldig then //...

Dit werkt uiteraard alleen met gegevens die <=4 bytes zijn. Anders moet je handmatig geheugen gaan alloceren, OF de gegevens centraal opslaan en daarnaartoe een pointer maken. Het is nml algemeen geaccepteert dat je gegevens in tree/list nodes plempen erg vies is. Meestal heb je dan je gegevens opeens op twee plaatsen (in je business logic en in je GUI). Kijk hier dus mee uit.

[ Voor 13% gewijzigd door _Thanatos_ op 30-07-2006 22:27 ]

日本!🎌


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 23:30

Tomatoman

Fulltime prutser

Je kunt waar natuurlijk ook als een LongBool definiëren, dat net als een pointer een grootte van 32 bits heeft. Dat scheelt weer wat typecasts.
Delphi:
1
2
3
4
5
6
7
8
var
  Waar, Geldig: LongBool;
begin
  Waar := True;
  MyTreeNode.Data := Pointer(Waar);

  Geldig := LongBool(MyTreeNode.Data);
  if Geldig then ...

Een goede grap mag vrienden kosten.


Verwijderd

Delphi's Booleans zijn ook gewoon 32 bits, maar moeten idd eerst gecast worden voor de compiler 't snapt.

Pas overigens wel op bij het mixen van Booleans en LongBools: een Boolean True is 1, een LongBool True is -1 (behalve bij Delphi 2, daar is 't weer 1). Gelukkig is False altijd 0, dus daar is prima op te checken... :)

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 23:30

Tomatoman

Fulltime prutser

Verwijderd schreef op maandag 31 juli 2006 @ 17:31:
Delphi's Booleans zijn ook gewoon 32 bits, maar moeten idd eerst gecast worden voor de compiler 't snapt.

Pas overigens wel op bij het mixen van Booleans en LongBools: een Boolean True is 1, een LongBool True is -1 (behalve bij Delphi 2, daar is 't weer 1). Gelukkig is False altijd 0, dus daar is prima op te checken... :)
Iets nauwkeuriger: een Boolean True is altijd 1, een LongBool True is altijd ongelijk aan nul (dus 1, -1 en 999 zijn allemaal True).

Een goede grap mag vrienden kosten.


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 23-12-2025

_Thanatos_

Ja, en kaal

Afterlife, heb je weleens gekeken naar het resultaat van SizeOf(Boolean) ?

日本!🎌


Verwijderd

Oeps, je hebt gelijk...
Pagina: 1