Python und C/C++, aber wie?

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
Pythom
User
Beiträge: 4
Registriert: Mittwoch 20. Oktober 2004, 01:08

Es gibt verschiedene Tools die es leichter machen, die Kluft zwischen Python und C/C++ zu überbrücken:
Daß das dennoch keine simple Angelegenheit ist, ergibt sich schon aus der vielzahl der Tools und damit auch Lösungsansätzen.

Worum es mir geht, ist zunächst einmal ein allgemeines Verständnis für die Arbeitsweise dieser Tools zu entwickeln. Etwas über deren Vor- und Nachteile in deutscher Sprache zu erfahren, bevor ich mir die Mühe mache, mich detailiert in ein oder gar mehere Tools einzuarbeiten.

Wenn also jemand ein oder mehere dieser Tools soweit kennt, daß er ihre "Funktionsweise" beschreiben kann, dann bitte ich darum.
Ideal wäre eine Antwort auf die Frage, worin sich diese Tools unterscheiden.

1. SWIG - generate extension module from your .h files
2. boost.python - write (tiny) C++ class to wrap your classes in an extension module
3. Pyrex - write your extension module on Python (!)
4. CXX
5. SCXX
6. weave - include C code lines in Python program
7. SIP - similar to SWIG but specialised for Python and C++. Used to create PyQt, the Qt API wrapper library
8. ctypes is a Python module allowing to create and manipulate C data types in Python. These can then be passed to C-functions loaded from dynamic link libraries.
9. elmer - compile and run python code from C, as if it was written in C

http://wiki.python.org/moin/Integrating ... 95fd295e19

Danke, pythom

Edit (Leonidas): Sinnlose Umfrage gelöscht.
BlackJack

Pyrex und `ctypes` habe ich selbst schon benutzt und kann beides empfehlen. Wobei Pyrex nicht nur zum Verbinden von Python und C, sondern auch eine "eigenständige" Sprache ist. Als solche habe ich sie auch benutzt.

`ctypes` hat den Vorteil, dass es seit neuestem Bestandteil der Standardbibliothek ist, und dass man deshalb auf Plattformen, die traditionell keinen C-Compiler installiert haben und wo die Benutzer einen komisch angucken, wenn man zur Installation Compiler und die Kommandozeile statt Mausklicks benötigt, einfach eine vorkompilierte C-Bibliothek liefern kann. Diese ist im Gegensatz zu handgeschriebenen Python-Erweiterungs-Modulen unabhängig von der Python-Version.

Zur Arbeits- bzw. Funktionsweise der beiden:

Pyrex ist eine einerseits eingeschränkte Python-Sprachvariation, die andererseits statische typisierung mit C-Datentypen als Erweiterung bietet. Pyrex-Quelltext wird in C übersetzt, was man dann anschliessend in ein Python-Erweiterungsmodul übersetzen kann.

Es bietet sich zum Beispiel an, wenn man ein Python-Modul hat, welches "Low-Level"-Code enthält, der eigentlich komplett oder in Teilen in C geschrieben sein müsste um ordentliche Laufgeschwindigkeit zu erreichen. Dann kann man in einem ersten Schritt das Python-Modul so umschreiben, dass die Einschränkungen von Pyrex erfüllt werden, und danach die kritischen Teile mit den Pyrex-Erweiterungen der Sprache formulieren.

Vorteil dieses Vorgehens ist ein schnell(er) geschriebener Prototyp in Python, den man ausgiebig testen kann und der im Fehlerfall ordentliche Tracebacks statt falsche Daten oder Programmabstürze durch Speicherzugriffsfehler liefert. Und man kann auch die reine Python-Implementierung behalten, für Fälle wo man kein C-Modul übersetzen kann oder will.

Ein Beispiel für dieses Vorgehen kannst Du Dir hier anschauen: http://www.python-forum.de/post-34808.html#34808

Bei `ctypes` bildet man C-Datentypen und Strukturen in Python-Objekten nach und kann auf C-Funktionen in dynamisch geladenen Bibliotheken zugreifen. Man baut sozusagen die Header-Dateien in Python nach und kann dann eine Bibliothek benutzen, die gar nicht speziell für Python geschrieben sein muss. Das ist nützlich, wenn man auf Bibliotheken zugreifen will, die manche Hardwarehersteller ihren Produkten zusammen mit Informationen wie sie von C aus zu benutzen sind, beilegen. Mess- und Steuergeräte, Barcode-Scanner, und ähnliches zum Beispiel. Oder wenn man einen Prototyp einer Anwendung in Python Stück für Stück, oder zumindest die leistungskritischen Teile, in C umschreiben möchte.

Ansonsten habe ich noch schlechte Erfahrung mit SWIG beim installieren/kompilieren von Software gemacht, die SWIG verwendete. Im konkreten Fall waren das drei Komponenten von verschiedenen Anbietern die alle eine ganz spezielle SWIG-Version benötigten um übersetzt werden zu können. Es ging weder eine Revisionsnummer höher, noch niedriger. Ob das typisch für SWIG ist oder sich mittlerweile geändert hat, kann ich nicht sagen, aber empfand es damals als ziemlich nervend.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Pythom hat geschrieben: 1. SWIG - generate extension module from your .h files
2. boost.python - write (tiny) C++ class to wrap your classes in an extension module
Machen beide C/C++ Code aus einem Python-Programm nutzbar indem sie Module generieren, die dem CPython-Interpreter erlauben auf diese zuzugreifen.
Pythom hat geschrieben: 3. Pyrex - write your extension module on Python (!)
Das ist eine Art eingeschränktes Python, dass zu C kompiliert wird, welches dann zu einem Modul kompiliert werden kann, dass aus CPython nutzbar ist. WIrd häufig verwendet um irgendwelche Algoritmen zu beschleunigen.
Pythom hat geschrieben: 6. weave - include C code lines in Python program
C Inline in Python-Code. Igitt.
Pythom hat geschrieben: 7. SIP - similar to SWIG but specialised for Python and C++. Used to create PyQt, the Qt API wrapper library
Wie gesagt, ähnlich wie SWIG, nur soll es besser mit C++-Code zurechtkommen. AUßer PyQt wüsste ich nicht, was das nutzt.
Pythom hat geschrieben: 8. ctypes is a Python module allowing to create and manipulate C data types in Python. These can then be passed to C-functions loaded from dynamic link libraries.
Du kannst dadurch mehr oder weniger direkt auf C-Libraries zugreifen ohne irgendwas kompilieren zu müssen. Ist schon ziemlich praktisch, vor allem seitdem es in der Stdlib ist. Ich habe grade ein eigenes Projekt, das ctypes dafür nutzt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
HarryPython
User
Beiträge: 60
Registriert: Freitag 8. Juni 2007, 07:39

Hi

Also ich bin seit 2 Wochen dabei ein C++ Programm in Python zu übersetzen , benutze nur ctypes und das dazugehörige Tutorial. http://python.net/crew/theller/ctypes/tutorial.html Ich denke wenn ich besser in C++ wäre würde das bestimmt auch nicht so lange dauern. :roll:

Wenn ich dann machmal nicht weiter kam dachte ich auch an Boost aber das find ich einfach nur kompliziert. Bei ctypes kannst gleich loslegen und mit etwas Fantasie bekommt man das auch gut übersetzt.

Gruß Henry
Pythom
User
Beiträge: 4
Registriert: Mittwoch 20. Oktober 2004, 01:08

Für die Antworten möchte ich mich schon einmal bei allen Dreien bedanken! :)

Auch als Wiedereinsteiger erscheinen mir fast nur die 3 Tools: Ctype, Pyrex und Sip von Bedeutung.
Aber erlaubt meinem Hirn bitte kleine Schritte zu machen.
Erst einmal Pyrex:

Pyrex ist ein Python-Package und wird als solches in eine bestehende Python-Installation geladen. Nach dem download von Pyrex wird dieses in einem Ordner entpackt, bzw. mittels setup in Python installiert.
(Aktuelle Version 07.2007: Pyrex-0.9.5.1a -linux und 0.9.3.1-Windows --> http://www.cosc.canterbury.ac.nz/greg.e ... hon/Pyrex/)

Pyrex erweitert das normale Python um den Python-Dialekt, Pyrex.
Dabei verfügt Pyrex nahezu über das gleiche Vokabular, wie auch Python.
Es wird gesagt, Pyrex sei Python mit den Datentypen von C, als auch eine effiziente Sprache zum schreiben von Python-Erweiterungs-Modulen.

Der Pyrex Compiler kompiliert Python in einen C-Kode, welcher gleichsam die Python/C API aufrufen kann.
Dabei darf Kode, welcher Python Variablen verändert und solcher, welcher C-Daten verändert beliebig gemischt werden. Auch die Speicherverwaltung und Fehlerbehandlung geschieht unter Pyrex scheinbar automatisch.

Pyrex erweitert anscheinend lediglich das Python-Vokabular in der gewohnten Python-Syntax um einige Befehle zum steuern von Compiler und Linker, nebst C-Datentypen.

Daraus wäre zu folgern, das nun ein Python-Programmierer auch C-Programme schreiben kann, ohne die Sprache C auch nur entfernt zu kennen, soweit man von der Kenntnis der C-Datentypen einmal absieht.

An dieser Stelle unterlasse ich bewusst die Frage, ob Pyrex noch mehr kann. Vielmehr kommt es mir darauf an, meine bisher dargelegte Sicht zu prüfen und ggf. zur Diskussion zu stellen.

Für Widerspruch und Bestätigung danke ich. :)
pythom
Pythom
User
Beiträge: 4
Registriert: Mittwoch 20. Oktober 2004, 01:08

Harry,
vielleicht erleichtert dir ein C-Interpreter Deine Arbeit.
Die standard Version ist kostenlos und auch mit ChScite erweiterbar.

http://www.softintegration.com/
BlackJack

Was den Python-Teil angeht kümmert sich der Pyrex-Compiler schon um Speicherverwaltung und Ausnahmen, aber wenn man die C-Datentypen benutzt, muss man sich da schon selbst darum kümmern wenn man selber dynamisch Speicher anfordert. In dem verlinkten Beispiel im meinem letzten Beitrag habe ich mich darum "gedrückt", indem ich ein `array.array()` für den "dynamischen Teil" benutzt habe. Von diesem Python-Objekt, kann man nämlich die Adresse der enthaltenen Daten als `int` erfragen und die dann natürlich auf der C bzw. Pyrex-Seite in einen Pointer casten.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

HarryPython hat geschrieben:Also ich bin seit 2 Wochen dabei ein C++ Programm in Python zu übersetzen , benutze nur ctypes und das dazugehörige Tutorial.
Was meinst du mit "übersetzen"? Schreibst du das Programm in Python neu? Wenn ja, wozu brauchst du dann ``ctypes``?
HarryPython hat geschrieben:Ich denke wenn ich besser in C++ wäre würde das bestimmt auch nicht so lange dauern. :roll:
Wenn das nicht C++ sondern C wäre, dann wäre das bestimmt auch einfacher, denn C ist in dieser Hinsicht angenehmer.
HarryPython hat geschrieben:Wenn ich dann machmal nicht weiter kam dachte ich auch an Boost aber das find ich einfach nur kompliziert.
Richtig. Deswegen werden auch viele Teile von Boost in den C++0x-Standard übernommen ;)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Pythom hat geschrieben:Daraus wäre zu folgern, das nun ein Python-Programmierer auch C-Programme schreiben kann, ohne die Sprache C auch nur entfernt zu kennen, soweit man von der Kenntnis der C-Datentypen einmal absieht.
Nein, ich würde nicht sagen, dass das generell der Fall ist. Es gab ja mal ``py2c``, welches aber eben nichts geworden ist, weil die Sprachen sich vom Aufbau und der Funktionsweise zu sehr unterscheiden, als dass eine bloße Übersetzung einfach so funktionieren würde. Eher noch könnte man Python in einen Lisp-Dialekt übersetzen, da sind die Unterschiede schon geringer.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
HarryPython
User
Beiträge: 60
Registriert: Freitag 8. Juni 2007, 07:39

Hey Leonidas,
Was meinst du mit "übersetzen"? Schreibst du das Programm in Python neu? Wenn ja, wozu brauchst du dann ``ctypes``?
Das Programm spricht eine dll an die dann mit einer PCMCIA Karte kommuniziert. Und diese dll will halt ganz unbedingt C-Typen haben. Und das ist auch mein größtes Problem. Die Konvertierung der Typen. zB Erstellt Python PyHandle´s was aber nicht einem C Handle enspricht. Da muss man dann schreiben:

Code: Alles auswählen

C_Handle=ctypes.c_int(int(PyHandle))
Naja und was soll ich sagen...da muss man erstmal drauf kommen. Als nicht Programmierer. :wink: Das meinte ich mit Phantasie.
Und genau da hänge ich seit gestern schon wieder. Mein Aufruf

Code: Alles auswählen

vErr = self.candll.ncdReceive1(x,y))
für die dll erwartet bei y einen Pointer auf einen Pointer welcher von Typ Struct ist.
Meine Lösung:

Code: Alles auswählen

self.Vevent = s_vcan_event()  #s_vcan_event ist eine Klasse von Typ Struct
self.event = pointer(self.Vevent)

vErr = self.candll.ncdReceive1(x,byref(self.event))
Ich denke halt das der Pointer irgendwie kein C-Pointer ist oder so.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Für solche Fälle ist es eben nicht schlecht wenn man C kann und es auch versteht. Dann muss man zwar nicht unbedingt auch C schreiben, aber zum Anbinden von Bibliotheken via ``ctypes`` ist es von Vorteil.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sechsrad
User
Beiträge: 173
Registriert: Montag 31. März 2008, 17:09

Pyrex-Quelltext wird in C übersetzt, was man dann anschliessend in ein Python-Erweiterungsmodul übersetzen kann.

"Python-Erweiterungsmodul übersetzen kann." > wie geht das vom ablauf her, oder meinst du eine dll?

danke.

mfg
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

sechsrad hat geschrieben:"Python-Erweiterungsmodul übersetzen kann." > wie geht das vom ablauf her, oder meinst du eine dll?
Ja, beides eigentlich. Cython verarbeitet, ebenso wie Pyrex aus dem es hervorgegangen ist eine Art Python-Quelltext (es ist nicht wirklich Python-Quelltext, aber ähnlich nur mit weniger dynamischen Features). Diese Dateien werden dann in C-Dateien kompiliert, welche die C-API von CPython nutzen. Diese werden wiederum in Shared Objects kompiliert, welche von CPython importiert werden können.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten