Seite 1 von 1

ctypes Zugriff auf Rückgabe von frame_t * initFrame(..)

Verfasst: Donnerstag 26. Juni 2008, 14:14
von alban
Hallo,

Ich habe eine C-Funktion die eine Speicher mit malloc initialisiert und einen Pointer auf den kreierten Speicher zurückgibt. Die Definition der Funktion sieht wie folgt aus:

Code: Alles auswählen

frame_t * initFrame(int len);
Nun ist frame_t eine Struktur der Form:

Code: Alles auswählen

typedef struct {
    int N;
    int *array;
} frame_t;
Von dem frame_t habe ich eine Python Klasse erstellt:

Code: Alles auswählen

class Frame_t(Structure):
  _fields_ = [  ("N", c_int),
                ("array", POINTER(c_int))]
Jetzt habe ich versucht davon einen Pointer zu erzeugen und den dann als restype zu setzen, aber irgendwie funktioniert das nicht:

Code: Alles auswählen

frameP = POINTER(Frame_t)()

lib.initFrame.restype = frameP
Was mach ich denn hier falsch? In der Python Dokumentation wird das Beispiel mit einem c_char_p gezeigt:

http://docs.python.org/lib/ctypes-return-types.html

Wie sieht es denn mit dem kreierten Speicher aus? Kann ich den wieder von Python aus löschen? Dazu habe ich eine Funktion

Code: Alles auswählen

void freeFrame(frame_t * frame);
Kann ich die Funktion jetzt einfach mit dem frameP Pointer aufrufen?

Danke für die Hilfe,

Alban

Verfasst: Donnerstag 26. Juni 2008, 16:06
von BlackJack
Mit `ctypes.POINTER()` erzeugst Du ein Objekt, das in C einem Datentyp entspricht. *Das* brauchst Du um den Rückgabetyp anzugeben. Wenn Du dieses Typ-Objekt *aufrufst* bekommst Du ein *Exemplar* von dem Typ.

Verfasst: Freitag 27. Juni 2008, 19:19
von alban
BlackJack hat geschrieben:Mit `ctypes.POINTER()` erzeugst Du ein Objekt, das in C einem Datentyp entspricht. *Das* brauchst Du um den Rückgabetyp anzugeben.
Vielleicht verstehe ich das nicht ganz, aber ist nicht das was ich mache mit:

Code: Alles auswählen

frameP = POINTER(Frame_t)()

lib.initFrame.restype = frameP
Ich nehme das Object (frameP), das in C einem Datentyp entspricht und gebe es als Rückgabewert der funktion initFrame().
Wenn Du dieses Typ-Objekt *aufrufst* bekommst Du ein *Exemplar* von dem Typ.
Das heißt, ich muss frameP() aufrufen?

Verfasst: Freitag 27. Juni 2008, 20:23
von BlackJack
Du erzeugst ein Objekt, das einem Datentyp, d.h. einer Deklaration in C entspricht *und rufst das dann auf*, und erzeugst damit ein Exemplar von diesem Typ. Genau das ist aber ein Schritt zuviel, weil Du keinen konkreten Pointer vom Typ brauchst, sondern nur den Typ selber. ``POINTER(Frame_t)`` erzeugt den *Typ* ``*frame_t`` und ``POINTER(Frame_t)()`` erzeugt einen *Pointer* von diesem Typ.

Verfasst: Montag 30. Juni 2008, 08:50
von alban
Danke, jetzt habe ich es verstanden.