[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.
Antworten
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

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:

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

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

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
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

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

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:

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
Antworten