Autor Beitrag
Gewuerzgurke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 152

Win XP
Lazarus
BeitragVerfasst: Mi 01.07.09 18:17 
Hallo, ich suche nach einer Möglichkeit, den Typen eines Pointers zu ändern. Mein Problem: Ich habe zwei verschiedene Records. Jedes Record enhält eine (keine Ahnung, wie es in Records heist) "Variable" Transparency. Zu jedem Record habe ich auch den passenden Pointer. Also:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
type
 PRec1 = ^TRec1;
 TRec1 = record
  Transparency : Cardinal;
  AndereVariablen : sonstwas;
 end;
 PRec2 = ^TRec2;
 TRec2 = record
  Transparency : Cardinal;
  GanzAndereVariablen : irgendwas;
 end;

var
 Rec1 : TRec1;
 Rec2 : TRec2;


In meiner Funktion möchte ich die "Variable" Transparency über einen Poiner erreichen. Wenn ich den Pointer einrichte als PRec1 (also var DerPointer : PRec1;) dann kann ich damit die Variable in Rec2 nicht erreichen (außer Tranzparency steht - wie im Beispiel - in beiden Records an der selben Position, was ich aber in meinem Programm aus verschiedenen Gründen nicht verwirklichen kann...). Ich möchte wissen, ob man den Pointer zur Laufzeit von PRec1 in PRec2 ändern kann - oder ob es eine andere Lösung gibt.
Danke schonmal.
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Mi 01.07.09 18:27 
Schreib dir doch die Records wie folgt:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
type
 PRec1 = ^TRec1;
 TRec1 = record
  function gettransparency: Pointer;
  Transparency : Cardinal;
  AndereVariablen : sonstwas;
 end;
 PRec2 = ^TRec2;
 TRec2 = record
  function gettransparency: pointer;
  Transparency : Cardinal;
  GanzAndereVariablen : irgendwas;
 end;

var
 Rec1 : TRec1;
 Rec2 : TRec2;


...
function TRec1.gettransparency: pointer;
begin
  result := addr(Transparency);
end;


function TRec2.gettransparencypointer: pointer;
begin
  result := addr(Transparency);
end;



Die getter-Funktionen schreibst du dann an die selbe Stelle und ruftst den Wert Dann darüber ab.
Oder es geht villeicht auch mit einem explizitem Typecast, denn du weisst doch, welcher Record das ist?
mfg Boldar
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 01.07.09 18:30 
Moin!

Wozu gibt´s OOP?! :nixweiss: Ich würde da eine(n Satz) Klasse(n) draus machen. ;) Das Pointer-Gehake ist doch eher unschön... :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Gewuerzgurke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 152

Win XP
Lazarus
BeitragVerfasst: Mi 01.07.09 18:57 
Ja, ich habe auch immer versucht, Pointer zu vermeiden, aber dieses Mal geht es nicht anders... außer ich mache riesige "IF-Tabellen". OK, ich könnte auf die Variante mit "function gettransparency: Pointer;" zurückgreifen, aber das währe auch ziemlich aufwändig, wegen den Klassen. Ich hatte gehofft, dass es eine Möglichkeit gibt, nach dem Motto "Wenn Ziel_Von_Pointer = Rec2, dann Position_Von_Transparency = 1", was genau dem Problem mit dem ändern des Typen gleichkäme. Aber es muss doch eine Möglichkeit geben, die Variablen-Adressen abhängig von dem Typ des Records zu bekommen...
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Mi 01.07.09 19:02 
Meine oben genannte Methode arbeitet nicht mit Klassen, man muss es nicht uf Klassen umstellen, es muss nur eine Methode hinzugefügt werden.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 01.07.09 19:03 
Moin!

user profile iconGewuerzgurke hat folgendes geschrieben Zum zitierten Posting springen:
Ja, ich habe auch immer versucht, Pointer zu vermeiden, aber dieses Mal geht es nicht anders... außer ich mache riesige "IF-Tabellen". OK, ich könnte auf die Variante mit "function gettransparency: Pointer;" zurückgreifen, aber das währe auch ziemlich aufwändig, wegen den Klassen.
:gruebel:

Du kannst die records auch kaskadieren:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
type
  TDataRec1 = record
    //...
  end;

  TDataRec2 = record
    //...
  end;

  TCompositeRec1 = record
    Transparency: Cardinal;
    DataRec1: TDataRec1;
  end;

  TCompositeRec2 = record
    Transparency: Cardinal;
    DataRec2: TDataRec2;
  end;
Dann kannst du aber auch gleich eine Klasse nehmen, das ist definitiv besser. :nixweiss:

Vielleicht erklärst du mal kurz, was das werden soll, gibt ja vielleicht eine optimalere Alternative. :idea: ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19273
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 01.07.09 19:09 
Mir kämen da noch variante Records in den Sinn.
www.delphi-treff.de/...komplexe-datentypen/ hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
type
  person = record
    name: string;
    case erwachsen: boolean of
      true: (personalausweisnr: integer);
      false: (kinderausweisnr: integer;
        erziehungsberechtigte: string);
  end;
Ich nehme aber auch an, dass es eine bessere Lösung gibt...
Gewuerzgurke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 152

Win XP
Lazarus
BeitragVerfasst: Mi 01.07.09 19:41 
Also was ich machen möchte ist eine Animation (DirectX) mit verschiedenen Objekten. Es giebt verschiedene Sorten von Objekten. Für jede Sorte Objekt ist ein Array da, indem die Objekte "stehen" (Also var Sorte1 : Array of TSorte1;). Um ein Objekt zu verändern, z.B. ausblenden, giebt es eine procedure, die den Wert Transparency verändert. So ziemlich alle Objekte haben das Attribut Transparency, weswegen der Effekt Ausblenden auch auf alle Objekte anwendbar wäre. Aber dafür muss unterschieden werden, zu welcher Sorte das Objekt gehört. Mit einem Pointer könnte ich es mir ersparen, da große "IF-Tabellen" anzulegen. Aber dann habe ich das Problem mit dem Typen des Pointers. Ich glaube irgendwo gelesenzuhaben, dass man diesen Typen ändern kann, aber ganz so einfach ist es wohl nicht...

In diesem Fall würde es wirklich Sinn machen, darauf zu achten, dass Transparency immer an der selben Position im Record steht, aber das währe nicht so "sauber" - oder?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19273
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 01.07.09 20:11 
Du kannst die Pointer auch casten.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  a: TRec1;
  b: PRec1;
begin
  b := @a;
  PRec2(b).Transparency ...
Oder du kannst auch direkt die Speicherstelle benutzen. Allerdings solltest du dann einen packed record nehmen, damit die Variablen direkt hintereinander im Speicher liegen.
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Mi 01.07.09 22:20 
Für sowas kann man doch sehr gut Klassen nehmen, die sich dann selbst verwalten und evtl. selber zeichnen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19273
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 01.07.09 22:23 
Ja, sicher, sinnvoller wäre das mit Klassen wohl, wurde ja auch schon gesagt.

Insbesondere, weil man dann allgemeine Sachen in Elternklassen legen könnte und ggf. auch noch mit Interfaces arbeiten könnte. So könnte man das dann alles gleichzeitig erschlagen.
Reinhard Kern
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 591
Erhaltene Danke: 14



BeitragVerfasst: Mi 01.07.09 23:54 
user profile iconGewuerzgurke hat folgendes geschrieben Zum zitierten Posting springen:
Hallo, ich suche nach einer Möglichkeit, den Typen eines Pointers zu ändern.
....


Warum eigentlich, nimm doch einen Pointer direkt auf Transparency (eine Zuweisung an den Pointer brauchst du ja so oder so):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
type
 PTransparency = PCardinal;
 PRec1 = ^TRec1;
 TRec1 = record
  Transparency : Cardinal;
  AndereVariablen : sonstwas;
 end;
 PRec2 = ^TRec2;
 TRec2 = record
  Transparency : Cardinal;
  GanzAndereVariablen : irgendwas;
 end;

var
 PTrans : PTransparency;
 Rec1 : TRec1;
 Rec2 : TRec2;

begin
 PTrans := @Rec1.Transparency;
 PTrans := @Rec2.Transparency;


getestet hab ich das NICHT!

Gruss Reinhard
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19273
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 01.07.09 23:59 
Ja, das geht schon so denke ich. Man kann auch noch viel mehr Pointerspielerei hineinbringen. Z.B. um von einem allgemeinen Pointer auf einen der Records auszugehen kann man den auch auf PCardinal casten um auf den Cardinalwert am Anfang zuzugreifen.
SizeOf(Cardinal) = 4 Bytes später kommt dann die nächste Variable, ...

Aber das macht das alles natürlich nicht übersichtlicher. ;-)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 02.07.09 08:11 
Je nachdem, wieviele verschiedene Möglichkeiten es gibt, kann entweder die Variante mit dem Varianten Record ODER die Lösung über entsprechende Klassen übersichtlicher sein.

Keinesfalls sollte man aber unnötig Pointer-Casting betreiben, da das die Sache nicht übersichtlicher macht und eher Fehler provoziert.

Insgesamt wäre es aber durchaus mal sinnvoll, noch etwas mehr Quelltext zu bekommen, wie mit der Transparenz gearbeitet werden soll, da das so eher Spekulation ist ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Gewuerzgurke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 152

Win XP
Lazarus
BeitragVerfasst: Do 02.07.09 15:41 
@Reinhard Kern ( <-- Ist jetzt kein Pointer :mrgreen: ) - Hab' ich versucht - geht nicht. Es kommt zwar kein Fehler, aber es passiert auch nichts. Schade, denn das währe echt einfach gewesen. :(
Wenn ich den Pointer (Wie von jaenicke vorgeschlagen) caste (als PCardinal), dann funktioniert es zumindest dann, wenn Transparency als erstes im Record steht. Gibt es eine Möglichkeit, das Ganze nach hinten zu verschieben, soll heißen die Variablen, die vor Transparency kommen wieder "herauscasten"? Ich denk' mal, dafür muss ich dann packed record verwenden.

Wehe, wenn ich dann nochmal das Reckord verändere, aber ich gehe nicht davon aus, dass dies nötig sein wird.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19273
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 02.07.09 15:58 
user profile iconGewuerzgurke hat folgendes geschrieben Zum zitierten Posting springen:
@Reinhard Kern ( <-- Ist jetzt kein Pointer :mrgreen: ) - Hab' ich versucht - geht nicht.
Ich habe es getestet, das klappt bei mir problemlos. :gruebel:

user profile iconGewuerzgurke hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich den Pointer (Wie von jaenicke vorgeschlagen) caste (als PCardinal), dann funktioniert es zumindest dann, wenn Transparency als erstes im Record steht. Gibt es eine Möglichkeit, das Ganze nach hinten zu verschieben, soll heißen die Variablen, die vor Transparency kommen wieder "herauscasten"?
Wie ich schon sagte: Einfach den Pointer verschieben. Wenn davor ein Integerwert (4 Byte) steht so ca.:
ausblenden Delphi-Quelltext
1:
PTrans := PTransparency(Integer(@Rec1) + 4);					
Gewuerzgurke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 152

Win XP
Lazarus
BeitragVerfasst: Do 02.07.09 16:32 
Oh, nett, dass du es noch ausprobiert hast. Da muss ich wohl irgendwo einen Fehler gemacht haben. Ich probiere nochmal 'rum. :lupe:
Gewuerzgurke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 152

Win XP
Lazarus
BeitragVerfasst: So 05.07.09 19:24 
So, geht! :D

Mein Fehler war, dass ich versehendlich den Pointer, bevor dieser verwendet wird, nocheinmal zugewiesen habe (PTrans := @Rec1;). Da kann man vorher soviel richtig machen, wie man will :autsch: ...sowas blödes aber auch.