Seite 1 von 1

Py_Finalize() - embedding Python

Verfasst: Dienstag 10. November 2009, 20:42
von Maple99
Hi,

kurz mal eine Frage. Ich verwende ein Klasse bzw. eine Instanz dieser, die eine Methode besitzt die mir ein Dictionary liefert. Über dieses iteriere ich dann in C und hole mir mit PyDict_GetItem() die einzelnen Werte, die ich dann mit PyArg_Parse() in einen char* "umwandle". Jetzt habe ich das ganz starke Gefühl das zwar durch

Code: Alles auswählen

PyArg_Parse(myPyObject, "s", myString) 
intern ein malloc gemacht wird und der "Python-String" in einen neuen Speicherbereich geschrieben wird (myString zeigt dann auf diesen), aber wenn ich PyFinalize() aufrufe, dieser Speicherbereich mit freigegeben wird. Kann diese Vermutung jemand bestätigen oder vielleicht auch widerlegen? Nach einem PyFinalize() erhalte ich bei Zugriff auf diese Elemente jedenfalls einen Segmentation Fault :?

Gruß

Jonny

Verfasst: Mittwoch 11. November 2009, 08:51
von Zap
Ich bin jetzt nicht so Sattelfest was die C-Api von Python angeht.
Aber würde man bei deinem Vorhaben nicht sowas wie diese Funktion benutzen?

char* PyString_AsString(PyObject *string)

Die Beschreibung von PyArg_Parse passt IMHO nicht so ganz:
http://docs.python.org/c-api/arg.html#PyArg_Parse

Ich kann mich aber auch täuschen.

Re: Py_Finalize() - embedding Python

Verfasst: Mittwoch 11. November 2009, 09:35
von birkenfeld
Maple99 hat geschrieben:Hi,

kurz mal eine Frage. Ich verwende ein Klasse bzw. eine Instanz dieser, die eine Methode besitzt die mir ein Dictionary liefert. Über dieses iteriere ich dann in C und hole mir mit PyDict_GetItem() die einzelnen Werte, die ich dann mit PyArg_Parse() in einen char* "umwandle". Jetzt habe ich das ganz starke Gefühl das zwar durch

Code: Alles auswählen

PyArg_Parse(myPyObject, "s", myString) 
intern ein malloc gemacht wird und der "Python-String" in einen neuen Speicherbereich geschrieben wird (myString zeigt dann auf diesen), aber wenn ich PyFinalize() aufrufe, dieser Speicherbereich mit freigegeben wird. Kann diese Vermutung jemand bestätigen oder vielleicht auch widerlegen? Nach einem PyFinalize() erhalte ich bei Zugriff auf diese Elemente jedenfalls einen Segmentation Fault :?
Nein, PyArg_Parse(Tuple) selbst macht kein malloc. Dein char* zeigt auf den Speicherbereich mit dem String innerhalb des PyObjects, das den Python-String repräsentiert, und der wird beim Py_Finalize() zusammen mit allen anderen Python-Objekten deallokiert.

Wenn du den String selbst behalten möchtest, musst du ihn, z.B. mit strcpy(), kopieren, bevor du Py_Finalize() aufrufst.

Unabhängig davon hat Zap recht; PyArg_Parse ist an sich veraltet und hier völlig unnötig.

Verfasst: Mittwoch 11. November 2009, 17:58
von Maple99
Hi,

danke für eure Antworten.
Ich habe PyArg_Parse() benutzt, da ich unter Python3 entwickle und dort kein PyString_AsString() habe sondern nur das PyUnicode_AsUnicode() und damit kam ich irgendwie nicht so richtig klar. Mann mir jemand da vielleicht sagen wie ich denn den Unicode-String in einen ASCII-String (char *) bekomme??

Gruß

Jonny

Verfasst: Donnerstag 12. November 2009, 20:54
von Maple99
Hi,

hat keiner eine Idee? Wurde sowas noch nie gebraucht? Ich meine man muss doch in C auch mal mit den Strings hantieren.

Gruß

Jonny

Verfasst: Donnerstag 12. November 2009, 21:29
von BlackJack
@Maple99: Die Frage ist, wieviele Leute schon mit Python 3.x programmieren und dann auch noch C-Erweiterungen.

Ich würde das sowieso nicht mehr von Hand machen wollen. Wenn ich mehr Geschwindigkeit brauche, dann entweder Cython oder reines C und dann mittels `ctypes` anbinden.

Verfasst: Donnerstag 12. November 2009, 21:33
von Maple99
BlackJack hat geschrieben:Wenn ich mehr Geschwindigkeit brauche, dann entweder Cython oder reines C und dann mittels `ctypes` anbinden.
Arrr... sorry habe gerade den falschen Text hier gepostet. Sollte zum anderen Thread ;)

Danke dir für die Antwort. Meinst du die API wird so gar nicht mehr verwendet??

Verfasst: Donnerstag 12. November 2009, 22:49
von BlackJack
@Maple99: Die wird sicher noch so verwendet, aber nicht von mir. :-)

Cython erzeugt ja letztendlich auch eine C-Erweiterung, nur muss man selbst nicht den ganzen Boilerplate-Code schreiben (Referenzen, Ausnahmen usw.), sondern hat eine Python-ähnliche Syntax.

Und bei `ctypes` sehe ich den Vorteil darin, dass man nicht von der Python-Version abhängig ist. Bei einer C-Erweiterung ist es nicht ungewöhnlich, dass man die für jede Python-Minor-Version neu übersetzen muss. Das stellt oft Windowsbenutzer vor Probleme, wenn es eine Erweiterung für *ihre* Python-Version nicht vorkompiliert gibt, denn mal fix was selbst kompilieren ist in der Windowswelt nicht so verbreitet.

Aber Du willst ja anscheinend auch zusätzlich den Weg von der anderen Seite beschreiten, also Python in ein C-Programm einbetten. Da helfen Cython oder `ctypes` nicht viel weiter.

Verfasst: Donnerstag 12. November 2009, 23:21
von Maple99
Hey,

danke für deine Mühe. Ja ich wollte das ganze mal so von beiden Seiten beleuchten, aber ich werde mir dann auch mal Cython und ctypes anschauen. Danke.

Gruß

Jonny