Ich habe eine Reihe von Funktionen, die ich in C geschrieben habe, und ich hätte gerne Code, den ich in Python geschrieben habe, um auf diese Funktionen zugreifen zu können.
Ich habe hier mehrere Fragen gelesen, die sich mit einem ähnlichen Problem befassen (hier und hier zum Beispiel), aber ich bin verwirrt darüber, welchen Ansatz ich wählen muss.
Eine Frage empfiehlt ctypes und eine andere Cython. Ich habe für beide ein wenig Dokumentation gelesen und bin mir völlig unklar, welche für mich besser funktioniert.
Grundsätzlich habe ich Python-Code geschrieben, um zweidimensionale FFTs durchzuführen, und ich möchte, dass der C-Code dieses Ergebnis sehen und es dann durch die verschiedenen C-Funktionen verarbeiten kann, die ich geschrieben habe. Ich weiß nicht, ob es für mich einfacher sein wird, Python von C aus aufzurufen oder umgekehrt.
Sie sollten C von Python aus aufrufen, indem Sie a schreiben ctypen Verpackung. Cython dient dazu, Python-ähnlichen Code schneller laufen zu lassen, ctypes dient dazu, C-Funktionen von Python aus aufrufbar zu machen. Was Sie tun müssen, ist Folgendes:
Schreiben Sie die C-Funktionen, die Sie verwenden möchten. (Sie haben das wahrscheinlich schon getan)
Erstellen Sie für diese Funktionen ein gemeinsam genutztes Objekt (.so, für Linux, OS X usw.) oder eine dynamisch geladene Bibliothek (.dll, für Windows). (Vielleicht hast du das auch schon gemacht)
Rufen Sie eine Funktion aus diesem Wrapper in Python auf. (Dies ist genauso einfach wie das Aufrufen einer anderen Python-Funktion)
Da OP sowohl der Autor von C- als auch von Python-Code ist und OP lieber Python-Code schreibt, ist nicht klar, was hier verwendet werden sollte. Cython würde erlauben, mehr Code aus C zu ziehen.
– jfs
20. Mai 2013 um 16:09 Uhr
+1 für sachdienlichen Kommentar. Und Cython ist nicht nur eine Frage der Leistung. Es ist ein komplexes und mächtiges Werkzeug. Es erlaubt Ihnen, C-Code mit Python-Code zu mischen, wenn Sie also zufällig in C programmieren, kann es die perfekte Brücke zwischen C und Python sein. Das heißt, Sie können statisch (stark typisierte Variablen) mit dynamisch typisierten mischen. Und wechseln Sie von C (PyObject) Darstellung zu Python (object) Darstellung durch eine einfache castin beide Richtungen.
– Gauthier Boaglio
20. Mai 2013 um 17:05 Uhr
Sehr schönes Tutorial unter dem Link, aber ich musste ändern int sum zu int sum = 0 damit es richtig funktioniert.
– Akavall
20. Oktober 2017 um 0:16 Uhr
@Akavall Danke, behoben.
– Florian Reim
20. Oktober 2017 um 9:05 Uhr
Danke für den Tutorial-Link – wirklich schön. Das einzige, was ich ändern würde, ist der Name der Python-Funktion im Abschnitt „Basics“, da Sie „our_function“ überladen haben, was etwas verwirrend sein könnte.
– Dr. McCleod
21. Mai 2019 um 9:30 Uhr
Gauthier Boaglio
Wenn ich es richtig verstehe, haben Sie keine Präferenz für den Dialog als c => python oder wie python => c. In dem Fall würde ich empfehlen Cython. Es ist ziemlich offen für viele Arten von Manipulationen, insbesondere in Ihrem Fall das Aufrufen einer Funktion, die in Python von C geschrieben wurde.
Das folgende Beispiel geht davon aus, dass Sie eine Python-Klasse (self eine Instanz davon ist) und dass diese Klasse eine Methode (name method) möchten Sie diese Klasse aufrufen und sich mit dem Ergebnis befassen (hier a double) von C. Diese Funktion, geschrieben in a Cython extension würde Ihnen helfen, diesen Anruf zu tätigen.
cdef public api double cy_call_func_double(object self, char* method, bint *error):
if (hasattr(self, method)):
error[0] = 0
return getattr(self, method)();
else:
error[0] = 1
Auf der C-Seite können Sie den Aufruf dann wie folgt ausführen:
PyObject *py_obj = ....
...
if (py_obj) {
int error;
double result;
result = cy_call_func_double(py_obj, (char*)"initSimulation", &error);
cout << "Do something with the result : " << result << endl;
}
Wo PyObject ist ein struct bereitgestellt von der Python/C-API Nachdem Sie die py_obj (durch Gießen einer normalen Python objectin Ihrer Cython-Erweiterung wie folgt: <PyObject *>my_python_object), könnten Sie endlich anrufen initSimulation Methode drauf und mache etwas mit dem Ergebnis. (Hier ein doubleaber Cython kann leicht damit umgehen vectors, sets…)
Nun, ich bin mir bewusst, dass das, was ich gerade geschrieben habe, verwirrend sein kann, wenn Sie noch nie etwas geschrieben haben, das verwendet Cythonaber es soll eine kurze Demonstration der zahlreichen Dinge sein, die es für Sie tun kann verschmelzen.
Andererseits kann dieser Ansatz je nach Komplexität Ihrer Algorithmen mehr Zeit in Anspruch nehmen als das Umcodieren Ihres Python-Codes in C. Meiner Meinung nach ist es nur dann sinnvoll, Zeit in das Erlernen von Cython zu investieren, wenn Sie planen, diese Art von Bedürfnissen ziemlich oft zu haben …
Hoffe das war wenigstens informativ…
Vielen Dank! Es sieht so aus, als könnte ich mit dem gleichen Aufwand einfach in C umcodieren, also muss ich in diesem Fall nicht wirklich Cython verwenden. Aber ich vermute, dass ich diese Informationen in Zukunft sehr nützlich finden werde.
– Kitchi
21. Mai 2013 um 11:22 Uhr
Ist das C oder C++? cout ist Teil von , oder?
– Ayxan Haqverdili
6. Februar 2019 um 13:41 Uhr
Nun, hier beziehen Sie sich auf zwei der folgenden Dinge.
So rufen Sie die c-Funktion innerhalb von Python auf (Erweitern von Python)
So rufen Sie eine Python-Funktion / ein Skript aus einem C-Programm auf (Einbetten von Python)
Für #2 ist das ‘Python einbetten’
Sie können das folgende Codesegment verwenden:
#include "python.h"
int main(int argc, char *argv[]) {
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print 'Today is',ctime(time())\n");
/*Or if you want to run python file within from the C code*/
//pyRun_SimpleFile("Filename");
Py_Finalize();
return 0; }
Für #1 ist das ‘Python erweitern’
Dann wäre es am besten, Ctypes zu verwenden (übrigens portabel für alle Python-Varianten).
Es wird einfacher sein, C von Python aus aufzurufen. Ihr Szenario klingt seltsam – normalerweise schreiben die Leute den größten Teil des Codes in Python, mit Ausnahme des prozessorintensiven Teils, der in C geschrieben ist. Ist die zweidimensionale FFT der rechenintensive Teil Ihres Codes?
13837600cookie-checkAufruf von C-Funktionen in Pythonyes
Hast du eine Bibliothek? .Also ?
– ManuParra
20. Mai 2013 um 10:47 Uhr
Geteilte Bibliothek? g++ -shared -Wl,-soname,mylib.so -o mylib.so my.o ?
– ManuParra
20. Mai 2013 um 10:49 Uhr