[gelöst] Pointer von QByteArray Element umcasten

Du bist neu in der Welt von C++? Dann schau hier herein!
gooze
Beiträge: 24
Registriert: 2. März 2009 09:49

Beitrag von gooze »

es treibt mich echt zur Weissglut :evil:

Also vielleicht nochmal anders erklärt. In der Hoffnung das evtl. noch einer die rettende Idee hat.

In einem char Array liegen die folgenden Werte vor:
array[0] -> 00
array[1] -> 00
array[2] -> 03
array[3] -> E8

ich möchte nun diese 4 char Werte zusammenfassen als einen 32 Bit Wert. Also 00 00 03 E8.

Unter C funktioniert das wie folgt:
1. hole mir den Zeiger aus der ersten array Stelle &array[0]
2. diesen char* caste ich in einen 32bit Zeiger um. Auf einem 32bitter also
über unsigned int * = (unsigned int*)(&array[0]);
3. Hole ich mir den Inhalt des 32bit Zeigers über *(unsigned int*)
4. als ergebnis habe ich dann 0x00 0x00 0x03 0xE8 also 1000.

Probiere ich das hier unter QT bekomme ich aber mit einer ähnlichen Vorgehensweise 0xE8 0x03 0x00 0x00.

Woher kommt das?

gooze
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ich glaube es ist Zeit dies nach C++ Grundlagen zu verschieben :roll:
QByteArray::data() liefert ein char* Pointer zurück den Du genauso behandeln kannst wie Du es unter C machst...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
gooze
Beiträge: 24
Registriert: 2. März 2009 09:49

Beitrag von gooze »

Was das jetzt in den Grundlagen zu suchen hat ist mir echt schleierhaft und zeigt, dass Du meine Frage anscheinend nicht verstanden hast.

Dass mit QByteArray::data einen entsprechenden Zeiger zurückliefert ist mir auch bekannt. Kann ja schliesslich lesen.

Aber Danke für Deine Hilfe!

gooze
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

elegant würde ich die Lösung aber nicht nennen
Kommt drauf an :wink: ... ein (*(unsigned*)c_ptr) ist plattformabhängig und nenn ich daher _nicht_ "elegant". Wenn es für den Benutzer keinen merklichen Unterschied macht, würde ich auf jeden Fall die robustere, plattformunabhängige Lösung vorziehen.

Aber bei der Diskussion um toUInt habe ich dein ursprüngliches Problem überlesen... warum sollte in QByteArray eine falsche ByteOrder vorhanden sein? Ein (Q)ByteArray kann gar keine falsche Order haben, weil die Aufgabe des Arrays ist, die Daten zu speichern, nicht sie zu interpretieren (und erst da spielt die ByteOrder eine Rolle)....

Daher meine Frage: du hast den Inhalt der Datei (E:\TAB.DAT) verifiziert (Hex-Editor) und behauptest, nach "readAll()" liefert data[0] _nicht_ 1 (01h) und z.B. data[11] _nicht_ 232 (E8h)?
gooze
Beiträge: 24
Registriert: 2. März 2009 09:49

Beitrag von gooze »

mein Beispiel sollte jetzt nicht direkt plattformunabhängig sein und auch keine Lösung. Ich habe halt nur mehrere Varianten durchprobiert. Und da war die Version mit dem pointerinhalt für mich am verständlichsten erklärbar. Anfangs versuchte ich das natürlich mit reinterpret_cast<quint32*>(&array[0]) also mehr c++ konform und unabhängig. Aber da komme ich zum gleichen Ergebnis. Und mein letzter Test war halt die pure C Variante die ich dann auch gepostet hatte.

Zur Byte Order:
Die ist natürlich im Array in der gleichen Folge wie im File vorhanden.
Aber nach dem Umcasten des Pointers steht in meiner Variablen die ich dann in einem lineEdit ausgeben will halt nicht die Bytereihenfolge 1,2,3,4 des Wertes sondern 4,3,2,1. Und da frage ich mich
1. Warum ist das so?
2. Wer oder was dreht diese Ausgabe?
3. Und bitteschön -die Frage geht aber nicht an Dich- was hat das mit C+ + Grundlagen zu tun? Derjenige der mein Problem in die Grundlagenecke verschoben hat kann mir mein Grundlagendefizit ja vielleicht erklären. Vielleicht gibt es ja dann eine sinnigere Begründung für das Verschieben des Threads für mich als die Nennung einer Methode mit dessen Rückgabewerten als Lösung meines Problems.

gooze
Dateianhänge
Debugausgabe der Zeigeradressen und des Inhalts
Debugausgabe der Zeigeradressen und des Inhalts
pointerprob.PNG (107.84 KiB) 6832 mal betrachtet
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

reinterpret_cast<quint32*>(&array[0]) also mehr c++ konform und unabhängig.
Ein Cast ist ein Cast.. da bist du genauso plattformabhängig...
Aber nach dem Umcasten des Pointers steht in meiner Variablen die ich dann in einem lineEdit ausgeben will halt nicht die Bytereihenfolge 1,2,3,4 des Wertes sondern 4,3,2,1. Und da frage ich mich
Ich rate mal... du hast das nicht byte-für-byte verifiziert, sondern einfach das Ergebnis in einen QString gewandelt und ausgegeben....?
1. Warum ist das so?
ganz einfach... weil du vermutlich auf einem PC (little Endian) arbeitest.. da steht das höchstwertige bit an der höchsten Speicheradresse (da wo bei dir der Wert "0xE8" steht... mit anderen Worten: eben _weil_ du die ByteOrder nicht drehst, bekommst du den falschen Wert..
-die Frage geht aber nicht an Dich- was hat das mit C+ + Grundlagen zu tun?
Ich kann sie trotzdem beantworten: weil Qt (QByteArray) nichts dafür kann... Umgang mit Char-Arrays und Integer sind C++-Grundlagen



[EDIT]
Dein Printscreen liefert doch genau das erwartete:

0x00 0x00 0x03 0xE8
Rechnung für Little-Endian:

0*256^0 + 0*256^1 + 3*256^2 + 3*256^3
= 0 + 0 + 196608 + 3892314112 = 3892510720
gooze
Beiträge: 24
Registriert: 2. März 2009 09:49

Beitrag von gooze »

Aha, da lichtet sich also der Vorhang.
Also doch BigEndian LittleEndian Problem.

Jetzt wird es auch plausibel.
Die Datei schreibe ich als Speicherauszug von einem PPC -> Motorola -> BigEndian.

Lese ich die Datei in ein QByteArray ein, auch kein Problem da QT default mit BigEndian arbeitet. Daher passen auch die Speicherstellen im QByteArray mit den Stellen im File überein.

Nutze ich jedoch nun eine Std C++ Funktion, hier das casten des Pointers, greift das LittleEndian Format des Intel PC´s und schmeisst mir demzufolge die Bytes vertauscht raus.

gooze
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

ja und nein...
1xja.. der Speicherauszug von PPC wird Integer-Werte in Big-Endian beinhalten.

2x nein.. das hat nichts mit Qt zu tun (das wäre auch mit ANSI-C und "fread()" so) und da wird auch nichts "getauscht" (die 4 Bytes landen in genau von dir erwarteten Reihenfolge im Int-Wert). Nur die Interpretation ist eine andere... du kannst es drehen und wenden wie du willst: auf einem Little-Endian-System musst du die eingelesenen Big-Endian-Daten umdrehen..
gooze
Beiträge: 24
Registriert: 2. März 2009 09:49

Beitrag von gooze »

ob ja oder nein, hin oder her, den Grund für dieses Verhalten kann ich nun deuten und darauf kam es mir an.

Dank an alle die mir dabei geholfen haben.

gooze
Antworten