AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Arbeit mit Buffer

Ein Thema von Sebastian Nintemann · begonnen am 28. Mai 2003 · letzter Beitrag vom 28. Mai 2003
Antwort Antwort
Sebastian Nintemann
(Gast)

n/a Beiträge
 
#1

Arbeit mit Buffer

  Alt 28. Mai 2003, 15:06
Hallo!

Hab folgendes Problem:
Also ich hab nen Buffer (Array of Char), und weiß, das vier bestimmte bytes daraus einen Cardinal Wert darstellen. Wie kriege ich meinetwegen die bytes 4-8 in eine entsprechende Variable?
Ich brech mir hier irgendwie einen ab...

Gruß, Sebastian
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#2
  Alt 28. Mai 2003, 15:27
Moin Sebastian,

die Bestandteile des Arrays sind je 8 Bit gross, und sollen in eine 32 Bit grosse Variable.
Dazu muss dann nur das jeweilige Byte an die richtige Stelle geschoben werden, z.B. so:

  dwResult := byte(acBuf[4]) or (byte(acBuf[5]) shl 8) or (byte(acBuf[6]) shl 16) or (byte(acBuf[7]) shl 24); je nachdem, wie Du es haben willst, müssen die Indizes eventuell vertauscht werden.
Ist zwar ungetestet, sollte aber so gehen.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Sebastian Nintemann
(Gast)

n/a Beiträge
 
#3
  Alt 28. Mai 2003, 18:27
Hallo Christian, ich bin im Augenblick etwas ratlos.

Ich hatte versucht das so zu machen:
Delphi-Quellcode:
var
  P: PCardinal;
  C: Cardinal;
  //...
begin
  //... buffer füllen


  P := @buffer[4];
  C := P^;

  Memo1.Lines.Add(IntToStr(ord(PByteArray(@C)[0]))+' '+IntToStr(ord(PByteArray(@C)[1]))+' '+IntToStr(ord(PByteArray(@C)[2]))+' '+IntToStr(ord(PByteArray(@C)[3]))+' ');
 {so hab ich mir den Inhalt der 4 bytes anzeigen lassen, hat auch geklappt, 00, 00, 16, 66, das gleiche sagt mir der Hexviewer wenn die die Datei mit der der Buffer gefüllt wird lese.} 

  Memo1.Lines.Add(BytesToBinStr(@tagsize,4));
  {BytesToBinStr zeigt die bytes binär an. Funktion siehe unten. Binär sieht das jetzt so aus: 00000000 00000000 00010000 01000010. Gebe ich diesen Binärwert in den Windows-Rechner ein und stelle auf Dezimal um bekomme ich 4162. Das gleiche wenn ich deine Methode verwende.}

  Memo1.Lines.Add(IntToStr(C));
  {Hier steht jetzt 1108344832, egal ob ichs mit dem Pointer oder mit dem Kopieren der einzelnen bytes mache...}
end;


Hier noch die Funktion BytesToBinStr:
Delphi-Quellcode:
function BytesToBinStr(const bytes: PByteArray; const len: integer): string;
  var
    i,j: integer;
  begin
  result := '';
  for j := pred(len) downto 0 do
  begin

    result := ' ' + result;
    for i := 0 to 7 do
    begin
      if (bytes[j] and ($01 shl i))>0 then
      begin
        result := '1' + result;
      end
      else
      begin
        result := '0' + result;
      end;
    end;

  end;
  end;
Ich versteh einfach nicht wie aus $00 00 10 42 bzw 00000000 00000000 00010000 01000010 die Zahl 1108344832 wird. Ist das niederwertigste Bit nicht rechts?
Vielleicht hab ich auch einen Fehler in der BytesToBinStr Routine oder sonstwo, ich komm nicht drauf... Vielleicht weißt du ja weiter.
Ansonsten wär ich natürlich auch für Kritik dankbar (zB das man ein PByteArray so nicht verwenden sollte o.ä. )

Gruß, Sebastian

[EDIT]Hab mich mit der Hexzahl vertan, ist natürlich $00 00 10 42 (Dezimal:0,0,16,66), wie ich geschrieben hab[/EDIT]
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#4
  Alt 28. Mai 2003, 18:51
Moin Sebastian,

wie Du aus meinem Beispiel entnehmen kannst verschiebe ich die Bytes mit zunehmender Position im Array immer um ein weiteres Byte nach links (shl 8, shl 16, shl 24), da bei Intel üblich die Bytes in umgekehrter Reihenfolge gespeichert werden.

Wenn es sich bei den vier Byte tatsächlich um ein Cardinal handelt, wäre die Ausgabe 1108344832 absolut korrekt ($42100000 gespeichert als 00001042). Sollten es hingegegen um zwei WORDs handeln, hätte das eine den Wert 0, das andere 16912.

Ich weiss ja nicht, woher Deine Daten stammen, ich les' Dateien immer gerne in einen String ein, oder, falls ich die Dateistruktur kenne, ein einen (oder mehrere) passend deklarierte Records.
(jeweils mit Hilfe von TFileStream).
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Sebastian Nintemann
(Gast)

n/a Beiträge
 
#5
  Alt 28. Mai 2003, 19:32
Hi Christian, danke für die Antwort.
Ich lese auch eine Datei über einen TFileStream. Es handelt sich dabei um eine Mp3-Datei deren Id3v2 Tag ich lesen will. Bei dem Wert handelt es sich um einen sogenannten Synchsafe Integer, der (damit alte Player, die den Tag nicht kennen nicht versuchen den Tag als Ton auszugeben) das jeweils höchstwertige Bit eines Bytes auf 0 belässt (mit dem Ergebnis, dass Player kein zufällig entstehendes Mpeg-Synch-Signal erkennen). Dieses Bit wird dann 'ignoriert', herauskommt ein 28-Bit Wert.
Dieser Wert lautet korrekt: $00001042, und so steht er auch in der Datei, die Bytes nicht in umgekehrter Reihenfolge. Ich hab nun die 4 Bytes so in die Cardinal Variable gepackt, dass das vierte vorne steht und das erste hinten und siehe da: Dieser Wert, dekodiert durch meine SynchsafeInt-Funktion, liefert das passende Ergebnis.

Danke nochmal für die Hilfe! Gruß, Sebastian
  Mit Zitat antworten Zitat
tommie-lie
(Gast)

n/a Beiträge
 
#6
  Alt 28. Mai 2003, 20:03
Warum die Mühe?
UltimaTag
Macht zwar (noch) kein Unsyncing mit Frames, aber Header und der Rest werden schon, weil es sowieso im ID3v2.3-Standard so steht. Würde mich auch noch über weitere Tester und Frame-Wünsche freuen *g+
  Mit Zitat antworten Zitat
Sebastian Nintemann
(Gast)

n/a Beiträge
 
#7
  Alt 28. Mai 2003, 20:26
Zitat von tommie-lie:
Warum die Mühe?
Weil ich spaß dran hab

Im Ernst, mir ist schon klar, dass es für fast alles fertige Units und/oder Komponenten gibt, aber du musst zugeben, dass es ein wesentlich besseres Gefühl ist wenn man selbst ein Programm geschrieben hat, als wenn man sich drei Komponenten runtergeladen hat, diese auf das Formular gezogen, und auf Start gedrückt hat. Ich will ja auch was lernen, deswegen greife ich so gut wie nie auf Fremdkomponenten zurück (Natürlich gibt es auch Fälle wo das günstiger ist als selbst zu schreiben).
Werde mir deine Unit bei Gelegenheit aber auch mal angucken und testen!

Gruß, Sebastian
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz