IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Interfaçage autre langage Python Discussion :

[SWIG] dialogue entre code C et code python


Sujet :

Interfaçage autre langage Python

  1. #1
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut [SWIG] dialogue entre code C et code python
    Salut a Tous,

    J'ai un code en C (compose d'un fichier principale: main.c ... et d'un fichier qui contient quelques fonctions utiles: fonctions.c) dont je voudrais pouvoir scripter l'utilisation avec python.

    Aussi, je veux pouvoir appeler python a partir du code C. Pour cela, j'utilise Python.h et les fonctions PyRun_SimpleString & co. pour executer du code python a partir de main.c

    en gros (tres gros meme) ca ressemble a ca:

    main.c :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <Python.h>
     
    #include "fonctions.h"
     
    int main(){
     
       Py_Initialize();
       PyRun_SimpleString("code python here");
       Py_Finalize();
     
    }
    fonctions.c:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    #include "fonctions.h"
     
    void set_value_of_a(int x){
     
    a=x;
     
    }
    fonctions.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int a;
    void set_value_of_a(int x);

    ma fonction set_value_of_a() utilise donc la variable globale "a" definie dans "fonctions.h"... jusque la rien de speciale.


    Ensuite, j'utilise SWIG pour utiliser set_value_of_a() dans Python. Cela peut paraitre bizarre a 1ere vue....en effet pourquoi traduire du C en python pour ensuite apeler cela fonctions via C de nouveaux...autant utiliser la fonction C directement.

    Oui, mais je veux pouvoir benifier des fonctions python comme les boucles for et les conditions if/else. Ca serait beaucoup trop lourd a coder en C (ca serait comme re-inventer son propre language et compilateur !). Par example, l'utilisateur pourrait vouloir utiliser une boucle for pour donner une certaine valeur a , faire quelques trucs avec cette valeur, changer la valeur, refaire des trucs...etc....


    Bref, mon probleme se situe au niveau de la variable globale a. SWIG cree une variable cvar pour acceder au variable globale (avec module.cvar.a) mais cette variable est differente de ma variable a definie dans le code C.

    Comment faire pour que ce soit reellement la meme variable ? Quelqu'un a-t-il recontre le meme probleme ? y-a-t-il une solution ?

    meri d'avance.

    ps: j'esperes que mon explication etait assez clair ?
    pps: j'esperes aussi que c'est le bon forum...Swig est un peu a part mais pas assez populaire pour qu'il sa categorie propre je suppose

    David

  2. #2
    Membre éclairé Avatar de Bayard
    Inscrit en
    Juin 2002
    Messages
    863
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 863
    Par défaut
    Juste une question: vous désirez :

    • Soit appeler du code python depuis le langage C (cela corresponds à votre main())
    • Soit appeler du code C depuis le langage python (SWIG)

  3. #3
    Membre éclairé Avatar de Bayard
    Inscrit en
    Juin 2002
    Messages
    863
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 863

  4. #4
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut
    Juste une question: vous désirez :

    * Soit appeler du code python depuis le langage C (cela corresponds à votre main())
    * Soit appeler du code C depuis le langage python (SWIG)
    bah les deux en fait ! je veux appeler du code python a partie de C (pour benifier des boucles et conditions) et dans le code python utilise des fonctions C

  5. #5
    Membre éclairé Avatar de Bayard
    Inscrit en
    Juin 2002
    Messages
    863
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 863
    Par défaut
    Whauou, ceci n'est pas anodin.

    Je suggère de faire 2 post précis.

  6. #6
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut
    c'est assez complexe et surtout pas commun....
    Enfait, en reflechissant un peu, j'ai pu reduire tout ca a un problem peut-etre plus simple:


    Pour executer du code python a partir de C, il suffit de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <Python.h>
     
    int a;
     
    int main(){
     
       Py_Initialize();
       PyRun_SimpleString("code python here");
       Py_Finalize();
     
    }
    Maintenant, la question est : comment faire pour que le code python puisse acceder a des variables globales du code c (variable a dans mon example)?

    Est-ce possible ? A priori, le code python est completement independant du code c a partir duquel il est lance...donc aucune communication entre les deux....

  7. #7
    Membre éclairé
    Inscrit en
    Août 2006
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 46
    Par défaut
    Si tu as du code C avec des fonctions utiles que tu ne veux pas réecrire, mais que tu veux etre capable de les scripter en python ? Tu peux utiliser le package ctypes. C'ets justement prévu pour ça, et tu evite de passer par SWIG qui n'est pas toujours evident à utiliser je trouve.

    http://python.net/crew/theller/ctypes/

  8. #8
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut
    merci pour l'info, je ne connaissais que SWIG. Mais je pense me retrouver dans le meme probleme qu'avec SWIG: je vais me retrouver avec 2 codes independants qui ne pourront pas partager des variables.

    je vais surement regarder du cote des "shared memory programming"...

    a moins qu'il y ait une fonction dans Python. h qui permettre le feedback du code python dans le code C principal.

  9. #9
    Membre éclairé
    Inscrit en
    Août 2006
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 46
    Par défaut
    a moins qu'il y ait une fonction dans Python. h qui permettre le feedback du code python dans le code C principal.
    Je n'ai pas compris, feedback ?

    J'ai l'impression que tu confond entre 2 choses:
    - 2 programme qui s'execute separement et qui s'echange des données.
    - Le fait d'appeler dans le langage X un code ecrit en langage Y.

    1/ Pour appeler du code C dans python tu utilise SWIG ou mieux encore ctypes:
    cela nous permet de faire des trucs du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    y = []
    for x in range(1000):
        y.append(fonction_ecrite_c(x))
     
    ...
    2/ Si on veux recuperer le résultat de l'execution d'un programme X dans Y, on passe par un intermediare, il y a plusieur solutions:
    - Passer par un fichier
    - Appelé le programme X dans Y et récuperer la sortie (avec un pipe)
    etc.

    A ce que j'ai compris tu essai de faire en sorte que le programme Y set une variable globale qui elle est dans le programme X, seulement ca ne marche pas, car X et Y, ne partage pas le meme espace memoire et ce meme s'il ont en commun des bouts de code.

  10. #10
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    On peut echanger des données entre C et python, mais uniquement en paramètre ou retour de fonction, sauf erreur de ma part. Le bout de code qui suit récupère en C une variable globale python, puis appelle une fonction python qui incrémente une variable.

    Code test_python.c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <stdio.h>
    #include "C:\python24\include\Python.h"
     
    PyObject *mymod, *func, *pyparams, *retval;
     
    int CallPythonInc(int myint){
    	int js;
    	func = PyObject_GetAttrString(mymod, "PythonInc");
    	pyparams = Py_BuildValue("(l)", myint);
    	retval = PyEval_CallObject(func,pyparams);
    	PyArg_Parse(retval, "I",&js);
    	return js;
    }
     
    int CallPythonGet(void){
    	int js;
    	func = PyObject_GetAttrString(mymod, "PythonGet");
    	retval = PyEval_CallObject(func,NULL);
    	PyArg_Parse(retval, "l",&js);
    	return js;
    }
     
    int main(void){
    	int _result, _testvar = 1536;
    	Py_Initialize();
    	mymod = PyImport_ImportModule("python_sub");
     
    	_result = CallPythonGet();
    	printf ("Python global var:%u\n",_result);
     
    	_result = CallPythonInc(_testvar);
    	printf ("Initial value:%u Incremented value:%u\n",_testvar,_result);
     
    	Py_Finalize();
    	return 0;
    }

    Code python_sub.py : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    pythonvar = 123456789;
     
    def PythonInc(myint):
    	return myint + 1
     
    def PythonGet():
    	global pythonvar
    	return pythonvar

    Code compile.bat : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc test_c_python.c -L . -lpython24 -o test_c_python -Wall

    Il faut mettre la dll python dans le répertoire du projet. Pour le déploiement, ça risque d'être une véritable usine à gaz. Toutes les infos ont été trouvées là:
    http://docs.python.org/ext/intro.html
    A la moindre erreur de paramètre, on a droit à un magnifique message d'erreur de l'OS, car même si ça compile, ça plante. Je pense que la phase d'apprentissage sera douloureuse.

    A+

    Pfeuh

  11. #11
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut
    oh cool....merci beacoup ! ca a l'air d'etre exactement ce que je cherchais !
    cet example est vraiment tres utile.

    sais-tu comment faire pour recuperer une array de double par example a la placee d'un simple int ?

  12. #12
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,
    Citation Envoyé par dmichel Voir le message
    sais-tu comment faire pour recuperer une array de double par example a la placee d'un simple int ?
    Tout est là...
    http://docs.python.org/ext/intro.html
    Comme ça, à l'arrache? J'écrirais une fonction
    double GetDoubleByIdx(int idx)
    qui aurait en paramètre l'indice dans le tableau et qui retournerait le double.
    De toute façon, tu trouveras ton bonheur dans la doc, l'interface est bien faite et permet, comme python, de retourner à peu près n'importe quoi: Des strings, des listes, etc...


    A+

    Pfeuh

  13. #13
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut
    ok merci encore...c'est super useful :-)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Générateur de code C/C++ depuis Python
    Par SebGR dans le forum Interfaçage autre langage
    Réponses: 1
    Dernier message: 28/08/2008, 14h54
  2. dialogue entre une page web et un code C++builder
    Par tenebres dans le forum C++
    Réponses: 0
    Dernier message: 19/10/2007, 20h15
  3. integrer du code Assembleur (x86) dans python
    Par nephhh dans le forum Général Python
    Réponses: 2
    Dernier message: 11/02/2007, 11h50
  4. [C#] heritage entre form. excecution du code a la compil.
    Par jota5450 dans le forum Windows Forms
    Réponses: 8
    Dernier message: 07/07/2006, 10h30
  5. Réponses: 1
    Dernier message: 02/12/2005, 14h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo