Ich habe mal wieder eine ganz spezielle Frage, und ich hoffe, dass ihr mir dabei helfen könnt. Es handelt sich um eine rein theoretische Frage. Es geht um die Optimierung von Python, in dem ein Teil der Arbeit an C oder C++ übergeben wird. Wir schreiben ja immer, wenn jemand nach der Geschwindigkeit von Python fragt, dass man Python mit C oder C++ erweitern kann. Jetzt möchte ich wissen, wie das in der Praxis aussehen könnte. Mir ist dabei aber wichtig, dass man kein C-Könner sein muss. Jemand der mit Müh und Not eine Funktion in C zum Laufen bekommt, sollte damit auch zurecht kommen. Deshalb dachte ich zuerst mal an ctypes.
Wie macht man so etwas mit ctypes?
Wie man in diesem Thread http://www.python-forum.de/topic-7814.html sieht, hatte ich mich schon mal kurz damit befasst. Allerdings ist es ja nur bei der Übergabe von einfachem Text oder einfachen Zahlen so einfach wie im Beispiel.
Hier noch einmal das Beispiel aus oben genanntem Thread:
fib.c:
Code: Alles auswählen
// Das C-Programm
int fib(int n) {
if(n > 2)
return fib(n - 1) + fib(n - 2);
else
return 1;
}
Code: Alles auswählen
#!/usr/bin/env python
import ctypes
f = ctypes.cdll.LoadLibrary("fib.so")
print f.fib(35)
Code: Alles auswählen
#!/bin/bash
cc -c fib.c
cc -shared fib.o -o fib.so
LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:. python fibfast.py
In Python könnte das z.B. so aussehen:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
UNICODE_TEXT = u"""Hallo Welt. Ich bin gekommen um
zu bleiben. Brennspiritus, Isopropanol und Aceton sind
Stoffe, die man öfter bei Elektronikern anfindet.
Wickie ist der Sohn von Halvar (= Chef der Wickinger)."""
def get_words(text):
words = []
for line in text.splitlines():
for word in line.split():
word = word.replace("=", "")
word = word.strip("\n\r().,")
words.append(word)
return words
def main():
words = get_words(UNICODE_TEXT)
print repr(words)
if __name__ == "__main__":
main()
# Ausgabe:
# [u'Hallo', u'Welt', u'Ich', u'bin', u'gekommen', u'um', u'zu', u'bleiben',
# u'Brennspiritus', u'Isopropanol', u'und', u'Aceton', u'sind', u'Stoffe',
# u'die', u'man', u'\xf6fter', u'bei', u'Elektronikern', u'anfindet', u'Wickie',
#u'ist', u'der', u'Sohn', u'von', u'Halvar', u'', u'Chef', u'der', u'Wickinger']
Jetzt möchte ich diese Funktion in eine C- oder C++-Funktion auslagern. Am liebsten so, dass ich die Funktion über ctypes aufrufen kann, um von der eingesetzten Python-Version unabhängig zu bleiben. Die Schwierigkeiten sind: Es muss ein Unicode-Text an die C-Funktion übergeben werden (wie lange darf dieser sein?) und die C-Funktion sollte (wenn möglich) eine Python-Liste mit Unicode-Strings zurück liefern (Länge unbekannt). Wenn die Rückgabe einer Python-Liste nicht möglich ist, dann würde ich gerne wissen, welche Datenstruktur von der C-/C++-Funktion zurück gegeben werden muss, dass diese *ressourcenschonend* in Python in eine Python-Liste umgewandelt werden kann. Ist so etwas überhaupt möglich, ohne dass man in C gegen Python linkt?
Das ist etwas, was die wenigsten wissen und können. Deshalb bitte ich auch um funktionierende Beispiele in C/C++ und Python und um die entsprechenden Befehle um den Code zu kompilieren.
lg
Gerold