type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Tatsächlich. Eben probiert: Unter Windows geht es, unter Linux GTK2 bzw. Qt4 geht es nicht (gleiche Trunk-Versionen). Ist also ein WidGetSet-Problem.cle hat geschrieben:Ich habe vor zwei Tagen mit fpcupdeluxe Lazarus Trunk aktualisiert (Linux, 64, gtk2) und damit stürzt das Programm von oben wie gehabt ab. Mit Windows hat fpcupdeluxe nicht funktioniert, bei einem Laz 1.8.2 hat immerhin das if Assigned(Node.Data) gegriffen, im Gegensatz zu Linux.
Nur zur nachträglichen Info @Michl
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Michl hat geschrieben:Ja, es ist ein 64bit Problem. Wenn ich TOldTreeNodeInfo.Data auf PtrUInt umstelle, geht es auch unter einem 64bit Linux. Blöd ist halt, daß der Streamreader auch für die .lfm genutzt wird. Eine Änderung hier würde sich auf das Öffnen von 32bit erstellten Projekten mit einem 64bit Lazarus (und vice versa) auswirken.
procedure TTreeNode.ReadData(Stream: TStream; StreamVersion: integer);
...
Data := Pointer(PtrInt(OldInfo.Data)); // war: {%H-}Pointer(OldInfo.Data);
...
procedure TTreeNode.WriteData(Stream: TStream; StreamVersion: integer);
...
OldInfo.Data := Cardinal(PtrInt(Data)); // war: {%H-}Cardinal(Data);
...
procedure TTreeNode.WriteData(Stream: TStream; StreamVersion: integer);
...
writeln('TTreeNode.WriteData ', IntToHex(PtrUInt(Data), 16));
TTreeNode.WriteData 00007FFFF7FDE760
TTreeNode.WriteData 00000000010E3EC0
Ist gar nicht notwendig. Der 32bit Pointer wird einfach als "Platzhalter" mit gespeichert, für das Einlesen wird er nicht verwendet. Wenn man allerdings PtrUInt verwendet, ist unter 32bit der Platzhalter 4 Byte und unter 64bit 8 Byte groß. Daher verschieben sich alle Einträge, je nachdem ob man ein 32 oder 64bit Lazarus verwendet, um 4 Byte des Packed-Records TOldTreeNodeInfo. Es gibt neben der TOldTreeNodeInfo noch die TTreeNodeInfo ohne den Data Pointer. Weiß nicht, warum dieser Stream nicht für die .lfm verwendet wird?!wp_xyz hat geschrieben: Kann man in der lfm-Datei überhaupt einen "richtigen" Pointer auf einen Speicherbereich speichern?
Bei der .lfm mag das gehen, da die Pointer nicht benötigt werden, für das Assign sind jedoch die richtigen Pointer/Speicheradressen notwendig. Wie willst du das im Stream-Reader/-Writer unterscheiden, ob gerade die .lfm gelesen/geschrieben wird oder ob eine Speicheroperation vorliegt?wp_xyz hat geschrieben:Ich versteh das nicht: Kann man in der lfm-Datei überhaupt einen "richtigen" Pointer auf einen Speicherbereich speichern? Der Pointer zeigt nach dem Lesen der lfm-Datei mit sicherheit nicht auf die richtige Speicherstelle. Stattdessen wird man hier immer nur als Pointer "verkleidete" Integerwerte haben. Damit müsste man das Problem lösen können, wenn beim Lesen OldInfo.Data durch einen Cast auf PtrInt die 32-Bit Zahl OldInfo.Data bei 64-Bit auf die benötigte Pointer-Größe erweitert. Und beim Schreiben müsste man dasselbe tun und den zu großen PtrInt durch Cast auf Cardinal auf 32-Bit zurechtstutzen:
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Michl hat geschrieben:Bei der .lfm mag das gehen, da die Pointer nicht benötigt werden, für das Assign sind jedoch die richtigen Pointer/Speicheradressen notwendig. Wie willst du das im Stream-Reader/-Writer unterscheiden, ob gerade die .lfm gelesen/geschrieben wird oder ob eine Speicheroperation vorliegt?
procedure TTreeNode.Assign(Source: TPersistent);
var
ANode: TTreeNode;
begin
if Owner<>nil then Owner.ClearCache;
if Source is TTreeNode then
begin
ANode := TTreeNode(Source);
Text := ANode.Text;
Data := ANode.Data; // <------ hier: ANode.Data ist ein Pointer, kein Cardinal!
...
end
else inherited Assign(Source);
end;
Michl hat geschrieben:Es gibt neben der TOldTreeNodeInfo noch die TTreeNodeInfo ohne den Data Pointer. Weiß nicht, warum dieser Stream nicht für die .lfm verwendet wird?!
Michl hat geschrieben:Der 32bit Pointer wird einfach als "Platzhalter" mit gespeichert, für das Einlesen wird er nicht verwendet.
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Bei obrigen Beispiel wird die von dir aufgeführte Methode procedure TTreeNode.Assign(Source: TPersistent); gar nicht ausgeführt, da TreeView2.Items.Assign ReadData/WriteData ausführt (kannst ja einfach mal einen Breakpoint in die Methode setzen).wp_xyz hat geschrieben:Aber diese TOldTreeNodeInfo wird beim Assign gar nicht benötigt. sondern nur während ReadData/WriteData. Assign benutzt den Stream-Reader/Writer gar nicht - oder sehe ich da etwas falsch?
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Michl hat geschrieben:Lange Rede, kurzer Sinn, es funktioniert Data zu PtrUInt zu ändern und man kann ein Projekt trotzdem unter einem 32 oder 64bit Lazarus öffnen. Hatte mich schon gewundert, warum TOldTreeNodeInfo und nicht TTreeNodeInfo für das Speichern verwendet wird (was ja auch nicht stimmt). IMHO war es ein Copy&Paste Problem von TDelphiNodeInfo (Data hat da auch 32bit).
Ist jetzt gefixt in Lazarus Trunk Revision 58510.
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Michl hat geschrieben:Ich habe es jetzt nicht getestet, doch procedure TTreeNode.ReadDelphiData(Stream: TStream; Info: PDelphiNodeInfo); nutzt weiterhin folgendes: TDelphiNodeInfo.Data: Cardinal; // Always 32-bit, assigned to a Pointer.
In TTreeNode.ReadDelphiData bzw. TTreeNode.WriteDelphiData wird weiterhin zu Pointer <-> Cardinal gecastet. Sollte daher passen.
Die Records TOldTreeNodeInfo, TTreeNodeInfo und TDelphiNodeInfo sind von Haus aus nicht deckungsgleich und könnten somit sowieso nicht direkt aufeinander kopiert werden.
Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste