J'ai un tas de fonctions que j'ai écrites en C et j'aimerais avoir du code que j'ai écrit en Python pour pouvoir accéder à ces fonctions.
J'ai lu plusieurs questions ici qui traitent d'un problème similaire ( ici et ici par exemple) mais je ne sais pas quelle approche je dois adopter.
Une question recommande les ctypes et une autre recommande le cython. J'ai lu un peu de la documentation pour les deux, et je ne sais pas trop lequel fonctionnera le mieux pour moi.
Fondamentalement, j'ai écrit du code python pour faire des FFT bidimensionnelles et j'aimerais que le code C puisse voir ce résultat et ensuite le traiter à travers les différentes fonctions C que j'ai Je ne sais pas s'il sera plus facile pour moi d'appeler le Python de C ou vice versa.
Si je comprends bien, vous n'avez aucune préférence pour le dialogue comme c => python ou comme python => c. Dans ce cas, je recommanderais Cython
. Il est assez ouvert à de nombreux types de manipulation, spécialement, dans votre cas, appelant une fonction qui a été écrite en Python de C.
Voici comment cela fonctionne ( public api
):
L'exemple suivant suppose que vous avez une classe Python (self
en est une instance) et que cette classe a une méthode (nom method
) que vous veulent appeler cette classe et traiter le résultat (ici, un double
) de C. Cette fonction, écrite dans un Cython extension
vous aiderait à faire cet appel.
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
Côté C, vous pourrez alors effectuer l'appel comme suit:
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;
}
Où PyObject
est un struct
fourni par l'API Python/C Après avoir intercepté le py_obj
(en lançant un python object
, dans votre extension cython comme ceci: <PyObject *>my_python_object
), vous pourrez enfin appeler la méthode initSimulation
dessus et faire quelque chose avec le résultat. (Ici un double
, mais Cython peut facilement gérer vectors
, sets
, ... )
Eh bien, je suis conscient que ce que je viens d'écrire peut être déroutant si vous n'avez jamais rien écrit en utilisant Cython
, mais il vise à être une courte démonstration des nombreuses choses qu'il peut faire pour vous en termes de fusion .
D'un autre côté, cette approche peut prendre plus de temps que recoder votre code Python en C, selon la complexité de vos algorithmes. À mon avis, investir du temps dans l'apprentissage de Cython n'est pertinent que si vous prévoyez d'avoir ce genre de besoins assez souvent ...
J'espère que c'était au moins informatif ...
Vous devez appeler C depuis Python en écrivant un wrapper ctypes . Cython permet d'accélérer l'exécution de code de type python, ctypes sert à rendre les fonctions C appelables à partir de python. Ce que vous devez faire est le suivant:
Eh bien, ici, vous faites référence à deux choses ci-dessous.
Pour # 2, c'est 'Embedding Python'
Vous pouvez utiliser le segment de code ci-dessous:
#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; }
Pour # 1 c'est-à-dire 'Extension Python' Alors le meilleur pari serait d'utiliser des Ctypes (btw portable sur toutes les variantes) de python).
de l'importation de ctypes *
libc = cdll.msvcrt
imprimer libc.time (Aucun)
1438069008
printf = libc.printf
printf ("Bonjour,% s\n", "Monde!")
Bonjour le monde! 14
printf ("% d bouteilles de bière\n", 42)
42 bouteilles de bière 19
Pour un guide détaillé, vous pouvez vous référer à mon article de blog :
Il sera plus facile d'appeler C depuis python. Votre scénario semble étrange - normalement, les gens écrivent la plupart du code en python sauf pour la partie gourmande en processeur, qui est écrite en C. La FFT bidimensionnelle est-elle la partie gourmande en calcul de votre code?