Problem mit memcpy und struct
-
Hallo zusammen,
ich hab ein Problem bei der Benutzung von memcpy im Zusammenhang mit structs.
Ich programmiere mit C++ im Rahmen eines Qt Projekts.
Nach einem kurzen Blick in das Linux/Unix Forum und der Feststellung, dass die Beiträge
dort eher von der Natur "Hilfe mein X Server geht nicht mehr" sind dachte ich mir, dass ich
hier vielleicht eher Hilfe bekommen kannUm dieses struct handelt es sich (IconView_Type ist vom Typ int)
struct IconViewTypeAndText { IconView_Type type; QString text; };
Wird kodiert (im Rahmen von drag 'n drop) mit...
QByteArray array; IconViewTypeAndText * pData = new IconViewTypeAndText; pData->type = item->itemType(); pData->text = item->text(); array.resize( sizeof( pData ) ); memcpy( array.data(), pData, sizeof( pData ) ); setEncodedData( array );
... und dekodiert mit
QByteArray payload = mimeSource->encodedData(); IconViewTypeAndText * pData = new IconViewTypeAndText; memcpy( pData, payload.data(), sizeof( payload.data() ) );
Problem dabei ist jetzt, dass ich zwar auf pData->type zugreifen kann,
pData->text allerdings leer ist.
Woran könnte das liegen? Dass text ein QString ist vielleicht?UPDATE:
Bei anderer Reihenfolge im struct kann ich nun auf text
zugreifen, type ist dann immer NULL.
D.h. handelt sich entweder um ein size Problem oder ich hab bei der
Zuweisung irgendwo noch einen Fehler...LOESUNG:
Array Größe war das Problem.
Mit sizeof(pData)*2 und sizeof(payload.data())*2 gehtsDanke und Gruß,
andyknownasabu
-
Was ich auf den ersten Blick um die Uhrzeit sehe :
memcpy( array.data(), pData, sizeof( pData ) ); ???muesste das ned sizof(IconViewTypeAndText) heissen ?
Pdata ist nur der pointer, und duerfte damit immer 4 byte gross sein ?ne andere sache: QString text; mittels memcpy kopieren ist sehr mutig
memcpy auf wrapper kann die schoensten effekte erzeugen ... weisst du, was Qstring so alles mit seinem internen Zeiger so macht .... von denen solltest ne tiefe kopie machen .... und ned nur den zeiger ins byteArray ablegen ...
Hat Qstring ned ne moeglichkeit, sich in nem stream zu serializen, vielleicht solltest das nutzen ....Ciao ...
-
RHBaum schrieb:
Was ich auf den ersten Blick um die Uhrzeit sehe :
memcpy( array.data(), pData, sizeof( pData ) ); ???muesste das ned sizof(IconViewTypeAndText) heissen ?
Pdata ist nur der pointer, und duerfte damit immer 4 byte gross sein ?Jup, danke! Das war in der Tat genau das Problem (siehe meinen Beitrag).
Da hatte ich deinen allerdings noch gar nicht gelesen, jetzt hab
ichs also nochmal von xxx*2 auf deines geändert. Passt auchRHBaum schrieb:
ne andere sache: QString text; mittels memcpy kopieren ist sehr mutig
memcpy auf wrapper kann die schoensten effekte erzeugen ... weisst du, was Qstring so alles mit seinem internen Zeiger so macht .... von denen solltest ne tiefe kopie machen .... und ned nur den zeiger ins byteArray ablegen ...
Hat Qstring ned ne moeglichkeit, sich in nem stream zu serializen, vielleicht solltest das nutzen ....Mutig bin ich zwar, aber dann doch nicht _so_
Ne tiefe Kopie mach ich, hab ich nur nicht mehr extra dazugeschrieben...Danke für die Hilfe zu solch später Stunde!
-
ok, nun den ersten Kaffee hinter mir, nun bin ich auch streitlustiger
Sieht halt nur doof aus, QByteArray QString ... usw und memcpy im selben modul zu verwenden, den OOP Freaks wuerde der Kaffee nun nich mehr schmecken
Warum ned nen Wrapper fuer dein IconViewTypeAndText schreiben, und den ne Passende methode spendendieren, die Dir deine daten im ByteArray serialisiert.
Zumal ich ned ganz verstehe, wie du das teil wirklich ablegst. mit dem Memcopy kopierst du die rohdaten(den zeiger auf die zeichenkette) des QStrings ins Bytearray ... wo kopierst du die eigentliche zeichenkette hin, und beim auslesen, wie baust du das zusammen ? der zeiger nuetzt dir eigentlich gar nix ?
Ciao ...
-
RHBaum schrieb:
Sieht halt nur doof aus, QByteArray QString ... usw und memcpy im selben modul zu verwenden, den OOP Freaks wuerde der Kaffee nun nich mehr schmecken
Warum das? Ich verwende es in einer abgeleiteten Klasse von QDragObject...
Warum ned nen Wrapper fuer dein IconViewTypeAndText schreiben, und den ne Passende methode spendendieren, die Dir deine daten im ByteArray serialisiert.
Das würde sicher auch gehen, ich versteh allerdings noch nicht so recht den Vorteil oder warum das dann sauberer wäre als meine jetzige, funktionierende Methode... mal ganz abgesehen davon, das Serialisieren dann zu implementieren...
Zumal ich ned ganz verstehe, wie du das teil wirklich ablegst. mit dem Memcopy kopierst du die rohdaten(den zeiger auf die zeichenkette) des QStrings ins Bytearray ... wo kopierst du die eigentliche zeichenkette hin, und beim auslesen, wie baust du das zusammen ? der zeiger nuetzt dir eigentlich gar nix ?
Hm, ich muss zunächst sagen, dass ich in der Tat nicht genau weiß, ob und wie QString intern mit Zeigern hantiert.
Jedenfalls hab ich Beispielcode im Netz gefunden, es mit meinem struct genauso versucht und es funktioniertFolgendermaßen:
Bei "startDrag()" wird ein neues "OwnDragObject" erzeugt, das intern eben
diese beiden Daten - type<int> und text<QString> - des aktuell markierten "OwnIconViewItems" mit einer tiefen Kopie in ein QByteArray kopiert (memcpy).
Beim "contentsDropEvent" wird dann eine Methode der Klasse "OwnDragObject" aufgerufen, die diese Daten mittels memcpy wieder genauso in ein
IconViewTypeAndText zurückkopiert.
Zugreifen kann ich dann bequem mittels IconViewTypeAndText->[type|text]Für Drag 'n Drop hab ich im Netz ausser dem einen memcpy Beispiel nichts Weiteres gefunden.
Wenn es eine andere, "üblichere" Methode gibt beliebige Daten auf diese Weise zu übergeben würd mich das sehr interessieren... Nur raus damit
-
SPiel mal bisserl mit sizeof und Qstring rum, muesstest feststellen, das QString immer gleichgross bleibt, unabhaengig von der Zeichenkette die es verwaltet. Sicheres indiz dazu, das QString den speicher fuer die zeichenkette aufn dynamisch anlegt. Sprich du bekommst es nicht mit einem memcpy gebacken.
Was du brauchst, ist nen speicherblock wo alle "daten" am Stueck vorliegen ...
Moeglichkeiten
1.
Qstring gibt dir irgendwie nen zeiger auf die zeichenkette. Mit viel Glueck ist das kein Unicode, also kannst die daten mittels strlen/strcpy(alternativ memcpy) in dein Bytearray schieben, ansonsten wirds ein bisserl haariger. So kriegst es wenigstens zum funktionieren. Die OOP freaks sind aber immer noch ned gluecklich. memcpy/ strcpy solltest wirklich nur auf Array of PODs anwenden, und das auch ganz tief versteckt in privaten methoden.Du hasst hier voll nen allgemeines Problem. Braucht man ned nur per drag and drop, sondern bei allen moeglichen geschichten ( Moniker allgemein (CORBA z.b.) Netzwerk (Chatclients ... etc), Serialisierung ist nur nen kleiner teil. Die loesung Sind hier Datenstroeme. Und da das jeder braucht, gibts auch hilfe zu.
Schau dir mal QDataStream an ... da kannst deinen QString ganz locker unterbringen. vielleicht hast glueck, und dein Drag und Drop besteht ned so zwingend auf nen QByteArray ... sondern kann auch mit QDataStream arbeiten, dann wirds ganz einfach ... ansonsten musst noch QByteArray mit QDatastream verheiraten, was dir leider aber sicher noch ne zusaetzliche kopie einbringt. Und nen kurzer blick in die QT doku zeigt, das QByteArray und QDatastream sich ned ganz fremd sind, was die Hochzeit wesentlich vereinfachen duerft!
Hier werden dann auch dien OOPler gluecklich ... irgendwannVielleicht zeigst mal bisserl mehr code, dann kann ich auch genauer werden.
Ciao ...
P.S.
Nicht alles was man liest ist Gut ! Aber mit ein bisserl uebung kann mans irgendwann mal besser :pFür Drag 'n Drop hab ich im Netz ausser dem einen memcpy Beispiel nichts Weiteres gefunden.
Gib mal den Link, dann steinigen und federn wir den Author :p