[GELOEST] Einlesen von Binärdaten

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: Einlesen von Binärdaten

Beitrag von Komoluna »

Mathias hat geschrieben:Hast du mein Post wegen der Array auch gesehen ?

Verdammt, heißt es jetzt der, die oder das Array?
Oder gibts da nix allgemeingültiges?

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Einlesen von Binärdaten

Beitrag von wp_xyz »

photor hat geschrieben:Ich habe sie angehängt (bin aber nicht sicher, ob das klappt).

Nix da. Ich denke, du musst zippen, weil die Forumsoftware nichts anderes akzeptiert.

Benutzeravatar
photor
Beiträge: 443
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux: L 2.2.6 FPC 3.2.2 (Gtk2)
CPU-Target: 64Bit

Re: Einlesen von Binärdaten

Beitrag von photor »

Mathias hat geschrieben:Hast du mein Post wegen der Array auch gesehen ?

Ist bei i_getriebe[1] der erste Fehler ?


Hallo Mathias,

Gemach, gemach! Ich komme gerade vom Brötchen-Geld-Geber und arbeite gerade Eure vielfältigen Antworten ab :D

Da wollte ich erstmal fragen, ob es speicher-technisch einen Unterschied zwischen feld1 und feld2 gibt.

Code: Alles auswählen

 
feld1 : array[1..N] of double;
feld2 : array[0..N-1] of double;
 

Beide sollten doch N double-Werte aufnehmen können und - so folgere ich - auch gleich groß sein.

Aber es ist richtig, der erste Wert im Feld i_getriebe ist schon falsch.

Ciao,

Photor

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Einlesen von Binärdaten

Beitrag von Mathias »

Den Wert für MAXGANG müsste man auch noch haben.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Einlesen von Binärdaten

Beitrag von Mathias »

Da wollte ich erstmal fragen, ob es speicher-technisch einen Unterschied zwischen feld1 und feld2 gibt.

Ist genau gleich gross. Üblich ist aber, das man mit 0 beginnt,

Aber es ist richtig, der erste Wert im Feld i_getriebe ist schon falsch.

Was müsste im ersten Wert stehen, ansonsten ist ein Vergleich fast unmöglich.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Einlesen von Binärdaten

Beitrag von wp_xyz »

Zunächst stolpere ich über das Feld Name, das muss 130 Byte lang sein, sonst liefern alle folgenden Elemente Unsinn. (Oder wegen des 8-byte Aligments beginnt das nächste Feld automatisch bei Offset 136).

Damit bekomme ich mit meinem Hex-Editor ab "gaenge" vernünftige Werte, bis zu Offset 316, aber kann daran liegen, weil ich MAXGANG nicht kenne, genausowenig wie MAXPNT.
Dateianhänge
sr500-hex.png

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Einlesen von Binärdaten

Beitrag von Mathias »

@wp_xyz

Du hast bei i_gert[1] einen ganz anderern wer bekommen wie ich.
Ritzel, blatt, gaenge sehen bei mir Gleich aus.

Ich habe es versucht, so einzulesen:

Code: Alles auswählen

  Memo1.Lines.Add(IntToStr(RoadLoadData.z_ritzel));
  Memo1.Lines.Add(IntToStr(RoadLoadData.z_blatt));
  Memo1.Lines.Add(IntToStr(RoadLoadData.n_gaenge));
  Memo1.Lines.Add('');
  Memo1.Lines.Add(FloatToStr(RoadLoadData.i_getriebe[1]));
  Memo1.Lines.Add(FloatToStr(RoadLoadData.i_getriebe[2]));
  Memo1.Lines.Add(FloatToStr(RoadLoadData.i_getriebe[3]));
  Memo1.Lines.Add(FloatToStr(RoadLoadData.i_getriebe[4]))


Bei mir kommt folgendes:

Code: Alles auswählen

16
42
5
 
-1.02951149491566E-86
3.94265077575268E234
6.77050456775434E-220
52881799.9915781


PS: Was hast du da für ein Hex-Editor, welcher die Bezeichnungen des Records reinschreibt ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Einlesen von Binärdaten

Beitrag von wp_xyz »

Die -1.02951149491566E-86 steht am Offset 224, meine Zahl igetr[1] beginnt aber schon bei Offset 220, was allerdings nicht an einer 8-er Grenze ausgerichtet ist. Es wäre gut, wenn wir die zu erwartenden Werte kennen würden.

PS: Was hast du da für ein Hex-Editor, welcher die Bezeichnungen des Records reinschreibt ?

Eigenentwicklung vor langer Zeit für's Reverse Engineering unbekannter Dateien. Die Records muss man Element für Element aufbauen

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Einlesen von Binärdaten

Beitrag von Mathias »

Die -1.02951149491566E-86 steht am Offset 224, meine Zahl igetr[1] beginnt aber schon bei Offset 220,

Wie kann die schon bei 220 sein, befindet sich nicht dort noch der Bereich von n_gaenge ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Einlesen von Binärdaten

Beitrag von wp_xyz »

gaenge ist bei 216 bis 219 (6 byte "vers", 130 byte "name", 9x double = 72, 2*int = 8 --> macht 216)

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Einlesen von Binärdaten

Beitrag von Mathias »

Ich habe noch etwas enteckt.

Mache ich folgende Byte-Array rein, dann änder sich das Ergebniss nicht.

Code: Alles auswählen

    n_gaenge: int32; { Anzahl Gaenge [-] }
    ba: array[0..3] of byte;
    i_getriebe: array[1..MAXGANG] of double;

Aber mache ich folgendes:

Code: Alles auswählen

    n_gaenge: int32; { Anzahl Gaenge [-] }
    ba: array[0..4] of byte;  // Ein Byte mehr.
    i_getriebe: array[1..MAXGANG] of double;

Dann verschiebt sich die Double-Array um eine Position:

Code: Alles auswählen

16
42
5
 
3.94265077575268E234
6.77050456775434E-220
52881799.9915781
5.29750861208061E-315

So wie es aussieht, sind die Werte bis n_gaenge nicht ausgerichtet.
Aber sobald die Double-Array kommt, richtet fpc dies an den nächsten 32-Bit Wert aus.
Der C-Compiler macht eine ganz andere Ausrichtung.

So wie es aussieht, muss man jedes Byte einzeln aus dem Stream lesen. :roll:


PS: somit ist dies mit den 116 und 220 und 224 geklärt.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
photor
Beiträge: 443
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux: L 2.2.6 FPC 3.2.2 (Gtk2)
CPU-Target: 64Bit

Re: Einlesen von Binärdaten

Beitrag von photor »

Hallo Forum,

was geht denn hier ab? :shock: Ich hab mich doch gerade mal für eine Stunde zum Essen und für ein bisschen Hausarbeit verabschiedet.

wp_xyz hat geschrieben:Damit bekomme ich mit meinem Hex-Editor ab "gaenge" vernünftige Werte, bis zu Offset 316, aber kann daran liegen, weil ich MAXGANG nicht kenne, genausowenig wie MAXPNT.


Hier noch die fehlenden Infos:

Code: Alles auswählen

 
const
  { Daten-Version }
  VERS = '0.0.1';
  KENN = 'RL02';
  { Kennlinien }
  MAXGANG = 7;          { maximale Anzahl der Gaenge (dimension. Arrays) }
  MAXPNT = 60;          { maximale Anzahl Stützstelle für Kennlinien }
 

Ich versuche mal die "Soll"-Daten zu rekonstruieren. Liefere sie dann nach.

Edit: jetzt hab ich vor lauter :shock: doch vergessen, mich für Euer Engagement zu bedanken - nachgeholt: "DANKE!"

Ciao,

Photor

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Einlesen von Binärdaten

Beitrag von Mathias »

Da gibt es schon mal eine Differenz:

Code: Alles auswählen

FileSize: 1864
SizeOf: 1872


Beim einlesen knallt es jetzt auch, da MAXGANG und MAXPNT bekannt sind.

Code: Alles auswählen

  AssignFile(fRoadLoadData, 'sr500.rlx');
  Reset(fRoadLoadData);
  Read(fRoadLoadData, RoadLoadData);   


Er kann nicht mehr einlesen, als vorhanden ist,
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
photor
Beiträge: 443
Registriert: Mo 24. Jan 2011, 21:38
OS, Lazarus, FPC: Arch Linux: L 2.2.6 FPC 3.2.2 (Gtk2)
CPU-Target: 64Bit

Re: Einlesen von Binärdaten

Beitrag von photor »

Hallo Forum,

ich denke mittlerweile auch, dass es an irgendwelchen Füllbytes liegt, die Pascal einfügt, C aber nicht. Also wird es tatsächlich auf eine stückweises Einlesen herauslaufen müssen :(

Der Vollständigkeit halber habe ich mich mit einem Hex-Editor durch das Binär-File gearbeitet und die (meisten) Werte rekonstruiert:

Code: Alles auswählen

 
#b  type    name                        content             
---------------------------------------------------------------------------
6   char   Version                     RL02
128   char   Name                        SR 500 (Bj. 83)
1   double   Gewicht                     170                 (float 64 bit)
1   double   Sx                          0.65                (float 64 bit)
1   double   Sy                          0.8                 (float 64 bit)
1   double   Radstand                    1.4                 (float 64 bit)
1   double   Fläche                      0.97                (float 64 bit)
1   double   Cw                          0.66                (float 64 bit)
1   double   Umfang Rad                  2.024               (float 64 bit)
1   double   mu                          0.8                 (float 64 bit)
1   double   i_primär                    2.557               (float 64 bit)
1   integer   Z-Ritzel                    16                  (signed 32 bit)
1   integer   Z-Blatt                     42                  (signed 32 bit)
1   integer   Gänge                       5                   (signed 32 bit)
7   double   i_getriebe (7x)             2.357               (float 64 bit)
                                        1.555               (float 64 bit)
                                        1.19                (float 64 bit)
                                        0.961               (float 64 bit)
                                        0.778               (float 64 bit)
                                        0.0                 (float 64 bit)
                                        0.0                 (float 64 bit)
7   double   i_gesamt (7x)               15.820..            (float 64 bit)
                                        10.437..            (float 64 bit)
                                        7.987..             (float 64 bit)
                                        6.450..             (float 64 bit)
                                        5.222..             (float 64 bit)
                                        (undef)             (float 64 bit)
                                        (undef)             (float 64 bit)
1   double   n_Kupplung                  1700                (float 64 bit)
1   double   n_Schalt                    6800                (float 64 bit)
1   integer   Anzahl Punkte               51                  (signed 32 bit)
60   double   Drehzahl (60x)              -- 60x float 64 bit --
1   double   max. Drehzahl               7000.0              (float 64 bit)
60   double   Leistung (60x)              -- 60x float 64 bit --
1   double   max. Leistung               23.958..            (float 64 bit)
1   double   Drehzahl max. P             6500.0              (float 64 bit)
60   double   Drehmoment (60x)            -- 60x float 64 bit --
1   double   Max. Drehmoment             39.3                (float 64 bit)
1   double   Drehzahl max. M             5500.0              (float 64 bit)
1   double   Steigung                    0.0                 (float 64 bit)
1   double   Windgeschwindigkeit         0.0                 (float 64 bit)
1   double   Gewicht Fahrer              100.0               (float 64 bit)
 


interessant finde ich noch die beiden Werte, die ich mit "(undef)" gekennzeichnet habe - heute würde ich dort explizit eine "0.0" (als float) eintragen. Die je 60 Werte für die Kennlinien habe ich jetzt nicht rekonstruiert; im File stehen dort jeweils 60 64-bit-floats.

Ciao,

Photor

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Einlesen von Binärdaten

Beitrag von Mathias »

So wie es aussieht, habe ich eine Lösung gefunden, es ist zwar mühsam, aber es geht.
Vielleicht könnte man gewisse Blöcke des Records am Stück einlesen, aber dann wird es unübersichtlich.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  FileStream: TFileStream;
  dummy: array[0..7] of byte;
  i: Integer;
begin
  FileStream := TFileStream.Create('sr500.rlx', fmOpenRead);
  Memo1.Clear;
 
  FileStream.Read(RoadLoadData.Vers,6);
  FileStream.Read(dummy, 2);
  FileStream.Read(RoadLoadData.Name, 128);
 
  FileStream.Read(RoadLoadData.Gewicht, 8);
  Memo1.Lines.Add(FloatToStr(RoadLoadData.Gewicht));
 
  FileStream.Read(RoadLoadData.sx, 8);
  Memo1.Lines.Add(FloatToStr(RoadLoadData.sx));
 
  FileStream.Read(RoadLoadData.sy, 8);
  Memo1.Lines.Add(FloatToStr(RoadLoadData.sy));
 
  FileStream.Read(RoadLoadData.Radstand, 8);
  Memo1.Lines.Add(FloatToStr(RoadLoadData.Radstand));
 
  FileStream.Read(RoadLoadData.Flaeche, 8);
  Memo1.Lines.Add(FloatToStr(RoadLoadData.Flaeche));
 
  FileStream.Read(RoadLoadData.cw, 8);
  Memo1.Lines.Add(FloatToStr(RoadLoadData.cw));
 
  FileStream.Read(RoadLoadData.Umfang, 8);
  Memo1.Lines.Add(FloatToStr(RoadLoadData.Umfang));
 
  FileStream.Read(RoadLoadData.mu, 8);
  Memo1.Lines.Add(FloatToStr(RoadLoadData.mu));
 
  FileStream.Read(RoadLoadData.i_prim, 8);
  Memo1.Lines.Add(FloatToStr(RoadLoadData.i_prim));
 
  Memo1.Lines.Add('');
 
  FileStream.Read(RoadLoadData.z_ritzel, 4);
  Memo1.Lines.Add(IntToStr(RoadLoadData.z_ritzel));
 
  FileStream.Read(RoadLoadData.z_blatt, 4);
  Memo1.Lines.Add(IntToStr(RoadLoadData.z_blatt));
 
  FileStream.Read(RoadLoadData.n_gaenge, 4);
  Memo1.Lines.Add(IntToStr(RoadLoadData.n_gaenge));
 
  Memo1.Lines.Add('');
 
  for i := 1 to MAXGANG do begin
    FileStream.Read(RoadLoadData.i_getriebe[i], 8);
    Memo1.Lines.Add(FloatToStr(RoadLoadData.i_getriebe[i]));
  end;
 
  FileStream.Free;
end;     
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten