Autor Beitrag
catweasel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: So 21.04.13 00:17 
Hi,

Ich habe hier ein kleines Problem. Es gibt eine Liste mit Objekten und sollen in einen FileStream geschrieben und wieder gelsen werden.
Beim Schreiben (scheint) alles soweit zu funktionieren. Und bei dem zugriff auf die Objekte geht auch alles glatt.
Nur beim Laden geht es nicht. :(

Beim debuggen triggert die Access Violation schon beim Zufriff auf die LoadFromStream Routine...
Ich kann einfach den Fhler nicht finden. Alle Objektinstanzen sollten eigentlich ordentlich erstellt sein. Der Zugriff auf zur Laufzeit erstellte Instazen klappt ja auch problemlos.

Um den Fehler zu reproduzieren: Ein paar neue Materialien erstellen und dann versuchen das MAterial Set zu speichern und wieder zu laden.
Warum scheitert der Zugriff auf FDisffuse.LoadFromStream()? :?

Ein ähnliches Problem gibt es auch bei den Laden/Speichern Routinen der T3DSceneClass. Erstellt einfach mal ein Objekt und versucht die Szene zu speichern / laden.

Wenn man versucht eine neue Kamera hinzu zu fügen... das Gleiche. Eine AV.. beim Zugriff auf FFOV. Warum :?:

Hinweis: Die neuen Objekte werden nur mit Dummy Daten gefüllt. Auch ansonsten ist das Programm natürlich noch an allen Fronten Baustelle.
Nur bringen mich diese Access Violation fast um den Verstand. Das ist seht hinderlich beim weitermachen....:cry:

Wäre echt super wenn mir jemand weiterhelfen könnte. :)

Cheers,
Catweasel
Einloggen, um Attachments anzusehen!
_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 21.04.13 09:13 
Das liegt an deiner Stringspeicherung in TStringValueClass. Du musst das erste Zeichen als Bufferstart übergeben, nicht den String-Pointer, der auf den String zeigt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
Size : longint;
begin
AStream.Read(Size,SizeOf(Size));
setlength(FText,Size);
AStream.Read(FText[1],Size);
end;

procedure TStringValueClass.SaveToStream(AStream: TFileStream);
var
Size : longint;
begin
Size := length(FText);
AStream.Write(Size,SizeOf(Size));
AStream.Write(FText[1],Size);
Bei der Gelegenheit würde ich auch gleich AnsiString nehmen, damit dein Dateiformat auch lesbar bleibt, wenn dein Projekt mit Delphi 2009 oder höher kompiliert wird. Und wenn du es ganz optimal willst, speichere den String als UTF8, dann geht auch Unicode ab Delphi 2009 und es bleibt kompatibel:
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:
function LoadStringFromStream(AStream: TStream): String;
var
  ResultString: AnsiString;
  StringSize: Integer;
begin
  Result := '';
  if AStream.Size - AStream.Position < SizeOf(StringSize) then
    Exit;
  AStream.ReadBuffer(StringSize, SizeOf(StringSize));
  SetLength(ResultString, StringSize);
  if AStream.Size - AStream.Position < StringSize then
    Exit;
  AStream.ReadBuffer(Pointer(ResultString)^, StringSize);
  {$ifdef UNICODE} // ab Delphi 2009
  Result := Utf8ToString(ResultString);
  {$else}
  Result := Utf8Decode(ResultString);
  {$endif}
end;

procedure SaveStringToStream(AStream: TStream; AString: String);
var
  StringSize: Integer;
  StringToSave: AnsiString;
begin
  StringToSave := Utf8Encode(AString);
  StringSize := Length(StringToSave);
  AStream.WriteBuffer(StringSize, SizeOf(StringSize));
  AStream.WriteBuffer(Pointer(StringToSave)^, StringSize);
end;

// ...

procedure TStringValueClass.LoadFromStream(AStream: TFileStream);
begin
  FText := LoadStringFromStream(AStream);
end;

procedure TStringValueClass.SaveToStream(AStream: TFileStream);
begin
  SaveStringToStream(AStream, FText);
end;
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: So 21.04.13 10:37 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Das liegt an deiner Stringspeicherung in TStringValueClass. Du musst das erste Zeichen als Bufferstart übergeben, nicht den String-Pointer, der auf den String zeigt:

Aua. :oops: Ich bin mal wieder darauf reingefallen das strings in Delphi nur wegen der Compiler Magic so bequem sind. Natürlich muss das eine Zeigerreferenz sein. :roll:

Vielen Dank für die schnelle Hilfe :)

An die Sache mit utf8 hatte ich noch garnicht gedacht... Danke für den Tip. Wird natürlich so umgesetzt ;)

Aaaaaber.. Ein kleines Problem gibts noch: Bei dem Versuch eine Kmera zu erstellen (wird weit und brei keine String Klasse verwendet).
D.h. dieser Fehler besteht weiterhin... :?
Sow wie ich das eingrenzen konnte schlägt es bei dem Zugriff auf FOVEdit.FloatValue1D (Unit UCameraDlg, Zeile 81) fehl.
Aber OriginEdit und DirectionEdit machen os ziemlich das selbe. Dort klappts... :?:

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 21.04.13 11:48 
Woanders kommt bei mir kein Fehler. Und FastMM findet zwar einige Speicherlecks, weil Klassen nicht wieder freigegeben werden, aber keine anderen Speicherprobleme.

Was genau machst du bis der Fehler kommt? Und kommt er dann bei dir immer?
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: So 21.04.13 13:17 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Woanders kommt bei mir kein Fehler. Und FastMM findet zwar einige Speicherlecks, weil Klassen nicht wieder freigegeben werden, aber keine anderen Speicherprobleme.

Was genau machst du bis der Fehler kommt? Und kommt er dann bei dir immer?


Ja, um das korekte Freigeben hab ich mich noch nicht gekümmert. DAs Programm leckt noch wie ein Sieb.
Der Fehler tritt bei mir auf sobald ich eine Kamera erstellen will. D.h: Anwendung starten. Auf Camera > New klicken.
Im Dialog was eintragen (oder Null Werte so lassen, macht keinen Unterschied) und dann auf Create klicken.
Dan kommt der Error.

Wenn ich in UCameraDlg Zeile 81 testhalber abändere in:  Result.FOV.Value := 0;//FOVEdit.FloatValue1D; dann klappt es.

Noch merkwürdiger: Ich habe mal probehalber das FOVEdit.Free; aus dem destructor entfernt. Dann funktioniert es ebenfalls :shock: ..

Igendwas muss da mit dem FOVEdit Objekt nicht stimmen. Die AV kommt also wenn entweder auf das Objekt zugegriffen wird, oder wenn es im destructor freigegeben wird.
Fast so als fände der Zugriff erst nach dem Zerstören es Elements statt. Der RenderSettings Dialog funktioniert auch klaglos. Ebenso die OriginEdit und ScaleEdit Objekte im Camera Dialog..

Der Fehler kommt jedesmal. Ich dachte schon das da irgendwo vielleicht ne race condition entsteht, aber das ist bei der Art wie der Dialog erzeugt wird (Tmainform.newcammnuClick in UMain) eigentlich nicht möglich....

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 21.04.13 17:18 
user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich in UCameraDlg Zeile 81 testhalber abändere in:  Result.FOV.Value := 0;//FOVEdit.FloatValue1D; dann klappt es
Da ich es nicht reproduzieren kann:
Was passiert, wenn du auf diese Zeile einen Haltepunkt setzt und den Wert von Self prüfst? Ist der vielleicht nil?
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: So 21.04.13 17:59 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich in UCameraDlg Zeile 81 testhalber abändere in:  Result.FOV.Value := 0;//FOVEdit.FloatValue1D; dann klappt es
Da ich es nicht reproduzieren kann:
Was passiert, wenn du auf diese Zeile einen Haltepunkt setzt und den Wert von Self prüfst? Ist der vielleicht nil?


Alles sit soweit referenziert (FOVEdit und 'self' natürlich auch), bis auf FloatValue1D. Dort sagt mir der Tooltip beim debuggen: Access Violation.
Ich habe einmal mein Fraps abgestaubt und ein kleines Demovideo von dem Programmverhalten gemacht. Bin gerade dabei das hochzuladen (youtube). Ich hoffe das klappt. KAnn nur etwas dauern. Aber im Laufe des Abends wird der Upload wohl durch sein.
Ich poste hier dann den Link zum Video.

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: So 21.04.13 19:05 
user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:
Ich poste hier dann den Link zum Video.


So.. Und hier isser : www.youtube.com/watch?v=3ZzKyIWQ1kI
Ich hoffe man kann es etwas erkennen...

Tip: Den Sound abdrehen ;)

Cheers,
Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.