Py_Finalize() - embedding Python

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
Maple99
User
Beiträge: 44
Registriert: Montag 14. September 2009, 18:08

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
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

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.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Maple99
User
Beiträge: 44
Registriert: Montag 14. September 2009, 18:08

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
Maple99
User
Beiträge: 44
Registriert: Montag 14. September 2009, 18:08

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
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.
Maple99
User
Beiträge: 44
Registriert: Montag 14. September 2009, 18:08

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??
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.
Maple99
User
Beiträge: 44
Registriert: Montag 14. September 2009, 18:08

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
Antworten