[cpython] Aufruf von Objektmethoden aus C

05/05/2010 - 10:24 von Ole Streicher | Report spam
Hallo Gruppe,

ich schreibe gerade eine C-Erweiterung für cpython, und ich muss dabei
über ein gegebenes Objekt iterieren. In Python sàhe ein Beispiel so aus:

def p(l):
for i in l:
print i

(i sind Strings)

Wie würde eine analoge Funktion in C aussehen? Ich dachte, etwa so
etwas:

static PyObject *
CPL_recipe_get_frameconfig(PyObject *self, PyObject *args) {
PyObject *l;
if (!PyArg_ParseTuple(args, "O", &l))
return NULL;

PyObject *iter_method = diese_funktion_fehlt(l, "__iter__");
if (iter_method == NULL)
return NULL;

PyObject *iterator = PyObject_CallObject(iter_method, Py_None);
PyObject *next_method = diese_funktion_fehlt(l, "__next__");
PyObject *next_object;
for (next_object = PyObject_CallObject(next_method, Py_None);
next_object != NULL;
next_object = PyObject_CallObject(next_method, Py_None)) {
char *s = diese_funktion_fehlt_auch(next_object);
printf("%s", s);
}

Py_INCREF(Py_None);
return Py_None;
}

Oder geht das für den speziellen Fall (iterieren über einen Container)
vielleicht sogar noch einfacher, ohne sich die passenden Methoden
herauszuziehen?

Viele Grüße

Ole
 

Lesen sie die antworten

#1 Thomas Rachel
05/05/2010 - 12:06 | Warnen spam
Am 05.05.2010 10:24, schrieb Ole Streicher:
Wie würde eine analoge Funktion in C aussehen? Ich dachte, etwa so
etwas:



Du suchst, glaube ich, http://docs.python.org/c-api/iter.html und evtl.
http://docs.python.org/c-api/object.html.

Nicht alle Iterables haben ein __iter__(); auch über Sequenzen kann
iteriert werden. Da wird dann __getitem__(k) für k=0..(ganz viel)
durchgeführt, bis ein IndexError kommt. Aus diesem Grunde soltle man für
die genannten Einsatzgebiete PyObject_GetIter(o) verwenden, was das, im
Gegensatz zu PyObject_GetAttrString(o, "__iter__"), richtig hinbekommt.


Ich habe früher auch einiges mit der C-Schnittstelle gemacht, hab mich
aber von der Gruppe davon überzeugen lassen, daß es (zumindest für die
eine Richtung, C-Aufrufe von python aus) per Modul ctypes einfacher und
schöner geht.


Die andere Richtung, Entwicklung von Plugins (PAM, Apache, ...), geht
bislang wohl so ohne weiteres nur "manuell", wobei man sich da IMHO in C
auf das Wesentlichste beschrànken sollte (Konvertierung von Daten ins
passende Parameterformat) und jegliche sonstige Logik nach Möglichkeit
in Python-Code ablegen sollte. Was Du da tust, sieht ein wenig danach
aus, als wolltest Du zu viel Logik in C-Code ablegen (muß aber nicht so
sein, kann mich da auch tàuschen)


Generell ist swig für diese Schnittstelle ein sehr hilfreiches Tool.


Thomas

Ähnliche fragen