[gefunden] ctypes Structure nach String und zurück wandeln

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

[gefunden] ctypes Structure nach String und zurück wandeln

Beitragvon rayo » Dienstag 21. November 2006, 16:07

Hi

Ein ctypes.Structure in einen String umwandeln funktioniert:

Code: Alles auswählen

buffer(struc)[:]


Jedoch möchte ich es wieder zurück von String nach Structure:

Code: Alles auswählen

buffer(struct)[0:len(raw)] = raw #geht nicht (python verabschiedet sich)


Was gibts da, um sowas zu bewerkstelligen?

Hier noch das Structure:

Code: Alles auswählen

class PTP_USB_Bulk_Params(ctypes.Structure):
    _fields_ = [
        ('param1', ctypes.c_uint),
        ('param2', ctypes.c_uint),
        ('param3', ctypes.c_uint),
        ('param4', ctypes.c_uint),
        ('param5', ctypes.c_uint),
               ]

PTP_USB_BULK_HS_MAX_PACKET_LEN = 4096
PTP_USB_BULK_HDR_LEN = (2*ctypes.sizeof(ctypes.c_uint)+2*ctypes.sizeof(ctypes.c_ushort))
PTP_USB_BULK_PAYLOAD_LEN = (PTP_USB_BULK_HS_MAX_PACKET_LEN-PTP_USB_BULK_HDR_LEN)
PTP_USB_BULK_REQ_LEN = (PTP_USB_BULK_HDR_LEN+5*ctypes.sizeof(ctypes.c_uint))

class PTP_USB_Bulk_Payload(ctypes.Union):
    _fields_ = [
        ('params', PTP_USB_Bulk_Params),
        ('data', ctypes.c_char*PTP_USB_BULK_PAYLOAD_LEN),
               ]

class PTP_USB_Bulk_Container(ctypes.Structure):
    _fields_ = [
        ('length', ctypes.c_uint),
        ('type', ctypes.c_ushort),
        ('code', ctypes.c_ushort),
        ('trans_id', ctypes.c_uint),
        ('payload', PTP_USB_Bulk_Payload)
               ]


Gruss
Zuletzt geändert von rayo am Dienstag 21. November 2006, 16:28, insgesamt 1-mal geändert.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Beitragvon rayo » Dienstag 21. November 2006, 16:28

Hi

Nach erneuertem Suchen hab ichs nun im ctypes-Wiki gefunden. Nach ein paar Namespace anpassungen hats auch funktioniert (sieht aber irgendwie Magic aus :) ):

Code: Alles auswählen

import ctypes

CharPtr = ctypes.POINTER(ctypes.c_char)
CharPtrPtr = ctypes.POINTER(CharPtr)
   
Py_ssize_t = ctypes.c_int
Py_ssize_t_Ptr = ctypes.POINTER(Py_ssize_t)
   
PyString_AsStringAndSize = ctypes.pythonapi.PyString_AsStringAndSize
PyString_AsStringAndSize.restype = ctypes.c_int
PyString_AsStringAndSize.argtypes = [ctypes.py_object, CharPtrPtr, Py_ssize_t_Ptr]

def from_string(s, c_obj):
    """Set contents of ctypes object c_obj to that of string s

    If the length of s is not the size of c_obj a SizeError
    exception is raised."""
    try:
        c_cp = CharPtr()
        c_sz = Py_ssize_t(0)
        PyString_AsStringAndSize(s, ctypes.byref(c_cp), ctypes.byref(c_sz))
        sz = c_sz.value
        if ctypes.sizeof(c_obj) != sz:
            raise "String and ctype object are different sizes [%d] [%d]"%(ctypes.sizeof(c_obj),sz)
        ctypes.memmove(ctypes.addressof(c_obj), c_cp, sz)
    finally:
        del c_cp  # Keep off traceback.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Dienstag 21. November 2006, 16:33

Wo für braucht man das :?
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Beitragvon rayo » Dienstag 21. November 2006, 19:29

Hi

Um mit einem MTP-Device (Media Transfer Protocol, gewisse MP3-Player) zu kommunizieren.

Da musst ich Rohdaten mit einer vorgegebenen Struktur schicken (C-Structs) und damit ich die schön ansprechen kann verwende ich ctypes.Structure, da das für C-Structs gemacht wurde.

Irgendwie wäre es schöner wenn ctypes so eine Funktion eingebaut hätte ... dann bräuchte man nicht so auf die Python-API zuzugreifen.

Gruss
Benutzeravatar
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Beitragvon Joghurt » Dienstag 21. November 2006, 21:55

rayo hat geschrieben:Da musst ich Rohdaten mit einer vorgegebenen Struktur schicken (C-Structs)
Und das geht nicht mit dem struct-Modul?
BlackJack

Beitragvon BlackJack » Mittwoch 22. November 2006, 00:34

Offensichtlich nicht, denn eine Zeichenkette die die entsprechenden Binärdaten enthält, hat er ja schon!
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Beitragvon rayo » Mittwoch 22. November 2006, 00:43

Hi

Also ich hab schon mal für ein anderes Projekt struct dazu verwendet, da hat es einfach keine vorgegebenen Funktionen dafür. Bei ctypes sind Unions und Structs scho eingebaut. die müsste ich bei struct selber schreiben.

Braucht beide Wege (String<->Struct).

Aber falls jemand Structs und Unions schon für das Modul Struct implementiert hat, darf er sich gerne bei mir melden.

Gruss

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder