Autor Beitrag
drstar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 79
Erhaltene Danke: 2

Windows 8.1/x64
Delphi 10.1
BeitragVerfasst: Di 21.11.17 19:00 
So, neues Problem, es nimmt kein Ende. Habe eine Klasse definiert, die aus Variablen und einer Property besteht, siehe folgenden Codeschnipsel:

ausblenden volle Höhe 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:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
type TK      = class(TKlient)
       private
         function onStreamRead : TMemoryStreamExt;
         procedure onStreamWrite(MemStream: TMemoryStreamExt);
       public
         constructor create;
         property MemStream : TMemoryStreamExt read OnStreamRead write onStreamWrite;
       end;

procedure TK.onStreamWrite(MemStream: TMemoryStreamExt);
var LocalStream: TMemoryStreamExt;
begin
  LocalStream := TMemoryStreamExt.Create;
  LocalStream.Read(self.Status, SizeOf(self.Status));
  LocalStream.Read(self.Index, SizeOf(self.Index));
  MemStream.CopyFrom(LocalStream, LocalStream.Size);
  LocalStream.Free;
end;

function  TK.onStreamRead: TMemoryStreamExt; //Erzeugen des Streams
const z: integer = 1;
var size: integer;
    LocalStream: TMemoryStreamExt;
begin
  LocalStream := TMemoryStreamExt.create;
  LocalStream.Write(z, SizeOf(z));  //Objekttyp
  LocalStream.Write(z, SizeOf(z));  //Größe - fürs Einlesen wichtig
  LocalStream.Write(self.Status, SizeOf(self.Status));
  LocalStream.Write(self.Index, SizeOf(self.Index));
// weitere Variablen in den Stream schmeißen
  LocalStream.Position := 4//Schreiben der Größe des Streams
  Size := LocalStream.size;
  LocalStream.write(Size, SizeOf(Size));
  Result.CopyFrom(LocalStream, LocalStream.Size);//  <--Hier kracht es
  MemStream.copyfrom(LocalStream, LocalStream.Size);//  <--kracht genauso
  LocalStream.free;
end;

constructor TK.create;
begin
  inherited;
  MemStream := TMemoryStreamExt.Create;
end;


Versuche ich den MemStream auszulesen (über onStreamRead als Getter) hagelt es eine Exception - versuche ich direkt MemStream zu befüllen ohne Umweg über LocalStream, hagelt es einen Stackoverflow. Wo liegt mein Denkfehler? TMemoryStreamExt ist aus TMemoryStream abgeleitet und um ReadString und WriteString ergänzt worden, sonst ein normaler TMemoryStream.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 21.11.17 19:33 
- Nachträglich durch die Entwickler-Ecke gelöscht -
drstar Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 79
Erhaltene Danke: 2

Windows 8.1/x64
Delphi 10.1
BeitragVerfasst: Di 21.11.17 19:46 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:


Außerdem: Soll das eine Eigenschaft sein, oder viel mehr ein Ereignis?


In gewisser Weise ein Ereignis. Hintergrund ist ganz banal: Ich lese Daten aus einem FileStream ein, und befülle damit die MemoryStreams der Klassen. Die zerlegen dann ihrerseits die MemoryStreams und befüllen damit ihre Variablen. Damit das Ganze wieder gespeichert werden kann, sollen sie dann ihrerseits aus den Variablen den MemoryStream befüllen, damit die dann wieder in einem FileStream landen können.

Verstehe ich Dich dahingehend richtig, daß es nicht möglich ist, MemStream in Form einer Klasse als Variable herhalten zu lassen?
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 21.11.17 20:15 
- Nachträglich durch die Entwickler-Ecke gelöscht -
drstar Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 79
Erhaltene Danke: 2

Windows 8.1/x64
Delphi 10.1
BeitragVerfasst: Mi 22.11.17 19:09 
wie es scheint, sind die auskommentierten Fragmente wohl die Lösung, nicht eine Alternative. Grund ist, daß FMemStream erst beim lesenden Zugriff von der Klasse selbst befüllt werden soll, um es dann zurückzuliefern. FMemStream wird demnach also nicht permanent aktuell gehalten, sondern erst beim Zugriff mit Daten befüllt. Allerdings kämpfe ich im Moment nun mit einem Problem an anderer Stelle, sodaß ich es noch nicht erfolgreich testen konnte.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 22.11.17 20:10 
- Nachträglich durch die Entwickler-Ecke gelöscht -
drstar Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 79
Erhaltene Danke: 2

Windows 8.1/x64
Delphi 10.1
BeitragVerfasst: Mi 22.11.17 21:28 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Die Getter und Setter Methoden machen hier nichts anderes, als aus der Variable FStream zu lesen:

ausblenden Delphi-Quelltext
1:
result := FStream;					

oder in sie zu schreiben:

ausblenden Delphi-Quelltext
1:
FStream := Value;					


Doch, sie machen mehr. Die Get-Methode (OnRead) befüllt den MemoryStream erst, denn er bleibt leer, bis auf ihn zugegriffen wird. Ohne die Get-Methode käme demzufolge ein leerer Stream zurück. Wie schon oben geschrieben, die Klasse befüllt den Stream nicht permanent, sondern nur, wenn er benötigt wird, indem auf ihn zugegriffen wird, ich habe bewußt auf eine dauerhafte Aktualisierung verzichtet.

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:

Daher kann es einen Unterschied zu:

ausblenden Delphi-Quelltext
1:
2:
3:
property MemStream: TMemoryStream read FStream write FStream;
property MemStream: TMemoryStream read GetStream write SetStream;
property MemStream: TMemoryStream read FStream write SetStream;

nicht geben


Eben deshalb müßte es also doch einen Unterschied machen, die Methoden sind zwingend, ein einfaches Auslesen tut es eben nicht.

So, mein neues Problem ist aber doch ein Problem - beim Auslesen des Streams mit

ausblenden Delphi-Quelltext
1:
Stream.copyfrom(K.MemStream, SizeOf(K.MemStream))					


erhalte ich einen Stream-Lesefehler, K ist eine Instanz von TK (s. o.). Wie komme ich an den Stream ran?
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 23.11.17 07:17 
- Nachträglich durch die Entwickler-Ecke gelöscht -
drstar Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 79
Erhaltene Danke: 2

Windows 8.1/x64
Delphi 10.1
BeitragVerfasst: Do 23.11.17 10:17 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:

[...]
Und was genau ist self.Status?


Status, Index, Name etc. sind Variablen, die die Klasse TKlientExt aus TKlient geerbt hat.

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:

Zitat:
So, mein neues Problem ist aber doch ein Problem - beim Auslesen des Streams mit

ausblenden Delphi-Quelltext
1:
Stream.copyfrom(K.MemStream, SizeOf(K.MemStream))					


erhalte ich einen Stream-Lesefehler, K ist eine Instanz von TK (s. o.). Wie komme ich an den Stream ran?

Hier wird nichts ausgelesen, sondern von MemStream nach Stream kopiert.
Stream sollte vorher eine (Start-)Position zugewiesen bekommen.


Stream hat ja eine Position. Es geht ja gerade darum, daß Stream sich den Inhalt aus den MemStreams der Klassen einsammelt und dann den ganzen Batzen in eine Datei schmeißt (bzw. umgekehrt aus der Datei liest und die MemStreams der Klassen damit füttert, die sich dann aus den MemStreams ihre benötigten Daten ziehen). Daher bringt es mir nichts, wenn die Klassen direkt in eine Datei schreiben, das soll ja der Hauptstream erledigen. Daher muß ich ja den Inhalt der MemStreams irgendwie in den Hauptstream bekommen. Ich dachte, mit der Read-Methode klappt es, klappt aber scheinbar nicht.

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:

Bitte gewöhn' es dir an, Getter-Methoden mit dem Prefix "Get" zu hinterlegen, sowie Setter-Methoden mit "Set".
Das "On" kündigt ein Ereignis an, und das führt sicherlich zu Missverständnissen, wenn ein Fremder deinen Code liest.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 23.11.17 13:34 
- Nachträglich durch die Entwickler-Ecke gelöscht -
drstar Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 79
Erhaltene Danke: 2

Windows 8.1/x64
Delphi 10.1
BeitragVerfasst: Do 23.11.17 22:15 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Status, Index, Name etc. sind Variablen, die die Klasse TKlientExt aus TKlient geerbt hat.

Wenn jene Attribute veröffentlcht wurden, dann sollten sie keine Variablen sondern Eigenschaften sein.
Geht es dir darum, die Werte zusammen zu fassen, in einen Stream zu laden, den Stream in einer Datei abzuspeichern und wieder retour zu auszulesen?


Ja, genau darum geht es mir. Aber ich will nicht den Aufwand betreiben, bei jeder Änderung einer Variablen den Stream neu zu erzeugen, sondern nur, wenn ein Zugriff auf diesen stattfindet. Daher sind es Variablen und keine Eigenschaften.
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 24.11.17 08:42 
- Nachträglich durch die Entwickler-Ecke gelöscht -