Seite 1 von 1
ctypes Strukturen und LittleEndian/BigEndian
Verfasst: Dienstag 3. September 2013, 17:12
von seux
Hallo zusammen,
ich habe eine eigene Structure mit ein paar Attributen. Diese Structure wird mit Bytes mithilfe der memmove funktion befüllt. Klappt auch wunderbar, allerings sind die Bytes für jedes Attribut nicht in der richtigen Byte reihenfolge. Gibt es eine Möglicheit, dies noch im nachhinein zu ändern und die Bytes ins LittleEndian format zu bringen?
vg, seux
Re: ctypes Strukturen und LittleEndian/BigEndian
Verfasst: Dienstag 3. September 2013, 21:52
von Sirius3
Kannst Du das näher erklären? Bytes sind Bytes, da gibt es keine Endiness.
Re: ctypes Strukturen und LittleEndian/BigEndian
Verfasst: Dienstag 3. September 2013, 23:25
von seux
Hier mal etwas Code:
Code: Alles auswählen
class Daten(Structure):
_fields_ = [
('name', c_ulong),
('version', c_ushort),
('data', c_ushort * 10),
]
Ich habe eine Struktur in dieser Form (kann aber später wesentlich mehr einträge beinhalten). Die Daten lese ich aus einer Datei ein und schiebe sie dann per memmove in die Struktur. wenn ich dann zum beispiel den Namen ausgebe, erhalte ich die 2 Bytes in der falschen reihenfolge. Dies gilt natürlich dann auch für die anderen Einträge.
Wie kann ich nun für jeden Eintrag die Byteorder ändern?
Re: ctypes Strukturen und LittleEndian/BigEndian
Verfasst: Dienstag 3. September 2013, 23:56
von EyDu
In der Dokumentation gibt es zur
Byte Order einen Abschnitt:
Code: Alles auswählen
>>> class Spam(ctypes.Structure):
... _fields_ = ("x", ctypes.c_int),
...
>>> s = Spam(1234567)
>>> str(buffer(s))
'\x87\xd6\x12\x00'
>>>
>>> class Ham(ctypes.BigEndianStructure):
... _fields_ = ("x", ctypes.c_int),
...
>>> h = Ham(1234567)
>>> str(buffer(h))
'\x00\x12\xd6\x87'
Re: ctypes Strukturen und LittleEndian/BigEndian
Verfasst: Mittwoch 4. September 2013, 00:33
von seux
@EyDu: Ich lese die Daten ja aus einer Datei ein. Sagen wir mal, ich lese 40 Bytes ein und speichere diese zwischen. laut types() entspricht dies dann einem String. Demnach kann ich das nicht so machen, wie du in deinem Beispiel. An der Stelle
erhalte ich, da es sich bei mir um einen String handelt einen TypeError. Deswegen hab ich die Daten auch mit memmove in die Structure geschoben
Re: ctypes Strukturen und LittleEndian/BigEndian
Verfasst: Mittwoch 4. September 2013, 01:00
von EyDu
Code: Alles auswählen
>>> s = Spam()
>>> h = Ham()
>>> ctypes.memmove(ctypes.addressof(s), '\x87\xd6\x12\x00', 4)
45782448
>>> s.x
1234567
>>> ctypes.memmove(ctypes.addressof(h), '\x87\xd6\x12\x00', 4)
45782304
>>> h.x
-2016013824
Meinst du so?
Edit: Man kommt doch auch sicher irgendwie ohne das addressof aus, oder?
Re: ctypes Strukturen und LittleEndian/BigEndian
Verfasst: Mittwoch 4. September 2013, 01:21
von seux
Ja, genau so, bloß das ich byref() statt adressof() verwende. Aber dein Vorschlag war schon die Lösung muss ich zugeben. Die Lösung mit dem ctypes.BigEndianStructure war doch richtig. Ich war wohl etwas dusselig und hab nicht gemerkt, dass die Bytes schon richtig angeordnet sind. Vielen Dank für die Hilfe
Re: [SOLVED] ctypes Strukturen und LittleEndian/BigEndian
Verfasst: Mittwoch 4. September 2013, 07:38
von BlackJack
Man könnte auch die `from_buffer_copy()`-Methode auf den Typobjekten verwenden um `memmove()` und `adressof()`/`byref()` und eine redundante Längenangabe zu vermeiden.