Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Tutorials und Kurse (https://www.delphipraxis.net/36-tutorials-und-kurse/)
-   -   Delphi Schlüsselwort absolute (https://www.delphipraxis.net/98080-schluesselwort-absolute.html)

Dezipaitor 21. Aug 2007 06:50


Schlüsselwort absolute
 
hi

kennt jemand noch das Delphischlüsselwort "absolute" ?
Mit dem kann man eine Speicherstelle durch eine weitere Variable beschreiben.

Delphi-Quellcode:
var i : Integer;
    i2 : Cardinal absolute i;
begin

Beide Variablen zeigen auf denselben Speicherbereich. Der Wert ist zwar der gleiche, jedoch nur dann, wenn i2 < high(i) is. Sonst wird i < 0.

Man kann dieses Spielchen auf für normale Parameter machen :
Delphi-Quellcode:
procedure XY(i : Integer);
var i2 : Cardinal absolute i;
begin
und für Rückgabewerte:

Delphi-Quellcode:
function XY : Integer;
var i2 : Cardinal absolute result;
begin
Wirklich nützlich ist das Schlüsselwort jedoch, wenn man einen Array hat, der aus der C Sparte stammt :

Delphi-Quellcode:
type  PData = ^TData;
       TData = record
         Member : ...
         ...
       end;


procedure XY(pArray : PData);
var  
   anArray : Array of pArray absolute pArray;
begin
In einem Array pArray, befinden sich die Elemente gerade soweit auseinander, wie die Größe von TData ist (ungepackter Zustand). D.h. wenn man durch die Elemente gehen will,
dann muss man normalerweise entweder :
1. Eine explizite Typkonvertierung machen
2. Einen Zeiger soweit verschieben, dass er aufs nächste Element zeigt.

Das ist jedoch nicht nötig.
Delphi-Quellcode:
procedure XY(pArray : PData);
var  
   anArray : Array of pArray absolute pArray;
   i : Integer;
begin
  for i := 0 to 5 do
    anArray[i].Member := ...;
Was jedoch notwendig ist, dass mann die Grenzen kennt. Die obere und die Untere. Man sollte nicht auf high(anArray), low(anArray) und length(anArray) vertrauen,
da der dynamische Array nicht korrekt erstellt wurde.
Zudem sollte man auf SetLength verzichten, da es sich ja garnicht um einen echten dynamischen delphi Array handelt.


Delphi-Quellcode:
procedure XY(pArray : PData; iCnt : Integer;);
var  
   anArray : Array of pArray absolute pArray;
   i : Integer;
begin
  for i := 0 to iCnt do
    anArray[i].Member := ...;

Zudem sollte man sowas immer kommentieren und nicht als Allheilmittel einsetzen.


Viel Spass

Relicted 21. Aug 2007 07:00

Re: Schlüsselwort absolute
 
huhu!

schickes tutorial... aaaaaaber :-) ich finde das absolute größtenteils nur für verwirrung sorgt. a) ist das wörtchen wirklich schon veraltet b) macht es den quellcode unleserlich (unkommentiert) und c) finde ich ist das ein nicht so schöner programmierstil.

absolute steht bei mir auf einer seperaten liste... wo z.b. "GoTo" mit draufsteht :-)
ich meine es ist jedem selbst überlassen es zu nutzen aber ob es wirklich "schön" ist bleibt für mich dahingestellt.

gruß
reli

Dezipaitor 21. Aug 2007 12:09

Re: Schlüsselwort absolute
 
Frage:
Wie würde man den untenstehenden Quelltext schreiben, ohne absolute zu verwenden?

Delphi-Quellcode:


type
  //aus jwaACLui.pas
  PSI_ACCESS = ^SI_ACCESS;
  {$EXTERNALSYM PSI_ACCESS}
  _SI_ACCESS = record
    pguid: LPGUID;
    mask: ACCESS_MASK;
    pszName: LPCWSTR; // may be resource ID
    dwFlags: DWORD;
  end;
  {$EXTERNALSYM _SI_ACCESS}
  SI_ACCESS = _SI_ACCESS;
  {$EXTERNALSYM SI_ACCESS}
  TSiAccess = SI_ACCESS;
  PSiAccess = PSI_ACCESS;

function GetAccessNames(out iCount : Cardinal): PSI_ACCESS;
var siArr : array of SI_ACCESS absolute result;
    i : Cardinal;  
begin
  iCount := 32;
  GetMem(result, Sizeof(si) * iCount);
  {result = siArr}
  for i := 0 to iCount -1 do
  begin
    hier zugriff auf siArr[i] ganz leicht
  end;
end;

Relicted 21. Aug 2007 12:15

Re: Schlüsselwort absolute
 
Zitat:

ich finde das absolute größtenteils nur für verwirrung sorgt
ich habe nicht gesagt dass es absolut nutzlos ist - natürlich gibts anwendungen wo man (fast?) nicht drum rum kommt. aber wenn man drum rum kommt sollte man es auch tun meiner meinung nach.

gruß
reli

jim_raynor 21. Aug 2007 12:33

Re: Schlüsselwort absolute
 
Zitat:

Zitat von Dezipaitor
Frage:
Wie würde man den untenstehenden Quelltext schreiben, ohne absolute zu verwenden?

Delphi-Quellcode:
type
  //aus jwaACLui.pas
  PSI_ACCESS = ^SI_ACCESS;
  {$EXTERNALSYM PSI_ACCESS}
  _SI_ACCESS = record
    pguid: LPGUID;
    mask: ACCESS_MASK;
    pszName: LPCWSTR; // may be resource ID
    dwFlags: DWORD;
  end;
  {$EXTERNALSYM _SI_ACCESS}
  SI_ACCESS = _SI_ACCESS;
  {$EXTERNALSYM SI_ACCESS}
  TSiAccess = SI_ACCESS;
  PSiAccess = PSI_ACCESS;

function GetAccessNames(out iCount : Cardinal): PSI_ACCESS;
var siArr : array of SI_ACCESS absolute result;
    i : Cardinal;  
begin
  iCount := 32;
  GetMem(result, Sizeof(si) * iCount);
  {result = siArr}
  for i := 0 to iCount -1 do
  begin
    hier zugriff auf siArr[i] ganz leicht
  end;
end;

IMO sollte es funktionieren, wenn PSI_ACCESS als Pointer auf ein Statisches Array definiert wird. Also:

Delphi-Quellcode:
type
  PSI_ACCESS = ^TSI_ACCESS;
  TSI_ACCESS_Array = Array[0..high(Integer)] of SI_ACCESS;
Natürlich darfst du so nie eine Variable direkt vom Typ TSI_ACCESS_Array anlegen, da sonst dein Stack sein voll dürfte.

Dezipaitor 21. Aug 2007 12:49

Re: Schlüsselwort absolute
 
Zitat:

Zitat von jim_raynor
Zitat:

Zitat von Dezipaitor
Frage:
Wie würde man den untenstehenden Quelltext schreiben, ohne absolute zu verwenden?

Delphi-Quellcode:
type
  //aus jwaACLui.pas
  PSI_ACCESS = ^SI_ACCESS;
  {$EXTERNALSYM PSI_ACCESS}
  _SI_ACCESS = record
    pguid: LPGUID;
    mask: ACCESS_MASK;
    pszName: LPCWSTR; // may be resource ID
    dwFlags: DWORD;
  end;
  {$EXTERNALSYM _SI_ACCESS}
  SI_ACCESS = _SI_ACCESS;
  {$EXTERNALSYM SI_ACCESS}
  TSiAccess = SI_ACCESS;
  PSiAccess = PSI_ACCESS;

IMO sollte es funktionieren, wenn PSI_ACCESS als Pointer auf ein Statisches Array definiert wird. Also:

Delphi-Quellcode:
type
  PSI_ACCESS = ^TSI_ACCESS;
  TSI_ACCESS_Array = Array[0..high(Integer)] of SI_ACCESS;
Natürlich darfst du so nie eine Variable direkt vom Typ TSI_ACCESS_Array anlegen, da sonst dein Stack sein voll dürfte.

Ich hab vergessen zu schreiben, dass der Typ _SI_ACCESS und alles was drumherum steht, nicht verändet werden darf. Es sind direkte Übersetzungen aus den C-Header-Dateien.


Es gibt aber eine Lösung, die das schafft. Leider ist sie etwas gefährlich.

Delphi-Quellcode:
class function GetAccessNames(out iCount : Cardinal): PSI_ACCESS;
type tASI = array of SI_ACCESS;
var
    siArr : tASI;
    i : Cardinal;
begin
  iCount := 32;
  GetMem(result, Sizeof(si) * iCount);
  {hier noch kein Zugriff auf siArr !!!!!!!}
 
  siArr := tASI(result);
  {result = siArr}
  for i := 0 to iCount -1 do
  begin
    //Zugriff : siArr[i]
  end;
end;

xaromz 21. Aug 2007 21:29

Re: Schlüsselwort absolute
 
Hallo,
Zitat:

Zitat von Dezipaitor
Es gibt aber eine Lösung, die das schafft. Leider ist sie etwas gefährlich.

Delphi-Quellcode:
class function GetAccessNames(out iCount : Cardinal): PSI_ACCESS;
type tASI = array of SI_ACCESS;
var
    siArr : tASI;
    i : Cardinal;
begin
  iCount := 32;
  GetMem(result, Sizeof(si) * iCount);
  {hier noch kein Zugriff auf siArr !!!!!!!}
 
  siArr := tASI(result);
  {result = siArr}
  for i := 0 to iCount -1 do
  begin
    //Zugriff : siArr[i]
  end;
end;

das ist eine ganz normale Lösung, die wunderbar funktioniert. Gefährlich ist die nicht, der Aufrufer darf nur nicht vergessen, den Speicher wieder freizugeben. Deshalb sollte für einen solchen Zweck eine Prozedur genommen werden, der man den Speicherbereich übergibt; dann muss der Aufrufer sowohl den Speicher anfordern als auch wieder freigeben. Deine erste Variante hingegen ist sehr gefährlich, da sie einen Pointer auf eine lokale Variable zurückgibt, der nach dem Aufruf nicht mehr gültig ist.

Gruß
xaromz

Muetze1 21. Aug 2007 21:40

Re: Schlüsselwort absolute
 
Mein Vorschlag:

Delphi-Quellcode:
function GetAccessNames(out iCount : Cardinal): PSI_ACCESS;
var lSiEntry: PSI_ACCESS;
    i : Cardinal;  
begin
  iCount := 32;
  GetMem(lSiEntry, Sizeof(si) * iCount);
  result := lSiEntry;

  for i := 0 to iCount -1 do
  begin
    hier zugriff auf lSiEntry^ ganz leicht

    Inc(lSiEntry);
  end;
end;
Der Vorschlag ist nur zum Elementzugriff. Die angesprochene Alloziierung von Speicher welche auf einer anderen Ebene freigegeben wird, ist hier nicht korrigiert und sollte wie von xaromz beschrieben gelöst werden.

stoxx 21. Aug 2007 21:44

Re: Schlüsselwort absolute
 
woher weiß ein C Programmierer, der nur einen Zeiger auf PData hat, wann das Ende des Arrays erreicht ist?

FAlter 21. Aug 2007 21:57

Re: Schlüsselwort absolute
 
Hi,

Zitat:

Zitat von jim_raynor
IMO sollte es funktionieren, wenn PSI_ACCESS als Pointer auf ein Statisches Array definiert wird. Also:

Delphi-Quellcode:
type
  PSI_ACCESS = ^TSI_ACCESS;
  TSI_ACCESS_Array = Array[0..high(Integer)] of SI_ACCESS;
Natürlich darfst du so nie eine Variable direkt vom Typ TSI_ACCESS_Array anlegen, da sonst dein Stack sein voll dürfte.

Delphi-Quellcode:
type
  PSI_ACCESS = ^TSI_ACCESS;
  TSI_ACCESS_Array = Array[0..0] of SI_ACCESS;
So sollte es imho auch gehen - und ohne Stackprobleme.

Mfg
FAlter (der übrigens auch kein absolute mehr nutzt)


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:30 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz