Seite 1 von 1

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

Verfasst: Dienstag 21. November 2006, 16:07
von rayo
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

Verfasst: Dienstag 21. November 2006, 16:28
von rayo
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.

Verfasst: Dienstag 21. November 2006, 16:33
von sape
Wo für braucht man das :?

Verfasst: Dienstag 21. November 2006, 19:29
von rayo
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

Verfasst: Dienstag 21. November 2006, 21:55
von Joghurt
rayo hat geschrieben:Da musst ich Rohdaten mit einer vorgegebenen Struktur schicken (C-Structs)
Und das geht nicht mit dem struct-Modul?

Verfasst: Mittwoch 22. November 2006, 00:34
von BlackJack
Offensichtlich nicht, denn eine Zeichenkette die die entsprechenden Binärdaten enthält, hat er ja schon!

Verfasst: Mittwoch 22. November 2006, 00:43
von rayo
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