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

C++ Discussion :

Appel d'un script Python dans C++


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut Appel d'un script Python dans C++


    Je m'essaye aux appels d'un script Python dans un code C++ et je suis tombé sur la page suivante de la doc officielle de Python : http://docs.python.org/3/extending/e...pure-embedding

    Malheureusement ça ne fonctionne pas comme voulu et je bloque notamment à la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pFunc = PyObject_GetAttrString(pModule, argv[2]);
    Voici ce que j'ai actuellement :

    test1.cpp
    Code : 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
    37
    38
    39
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    #include <Python.h>
     
    using namespace std;
     
    int main(int argc, char *argv[])
    {
        PyObject *pName, *pModule, *pDict, *pFunc;
        PyObject *pArgs, *pValue;
        int i;
     
        if (argc < 3) {
            fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
            return 1;
        }
     
        Py_Initialize();
        pName = PyUnicode_FromString(argv[1]);
     
        pModule = PyImport_Import(pName);
        Py_DECREF(pName);
     
        if (pModule != NULL) {
            pFunc = PyObject_GetAttrString(pModule, argv[2]);
     
            if (pFunc && PyCallable_Check(pFunc)) {
                cout << "Appel de la fonction " << argv[2] << " du module " << argv[1] << " réussi" << endl;
            }
            else
            {
                cout << "Erreur lors de l'appel de la fonction " << argv[2] << " du module " << argv[1] << endl;
            }
        }
        // je m'arrête volontairement là car je ne parviens pas à passer cette étape.
        Py_Finalize();
        return 0;
    }
    test.py
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def functTest(): 
        print("contrôle depuis Python : ok");
    test1.pro
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SOURCES += main.cpp
     
    LIBS += -L /usr/lib/python3.3/config-3.3m-x86_64-linux-gnu -lpython3.3
    INCLUDEPATH += -I /usr/include/python3.3m/
    Je suis assez ennuyé car il s'agit de la doc officielle et pourtant ça merdouille...

    Quelqu'un aurait-il une idée ?

    D'avance merci

    ++

    J
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Salut,

    Tu devrais plutôt t'attarder sur cet exemple simple : http://docs.python.org/3/extending/e...evel-embedding
    Le pure embedding a peu d'intérêt amha, l'essentiel étant à priori l'utilisation de http://docs.python.org/3/c-api/veryh...n_SimpleString pour réaliser import et appel de méthodes Python depuis le C++.

    Je vais pas pouvoir t'aider plus dans l'immédiat, mais ce soir de chez moi je pourrai te montrer comment réaliser ceci.
    S'il s'agit d'appeler des méthodes d'un script .py depuis le C++ c'est plus simple que l'inverse, mais l'initialisation de Python est un peu obscure et la doc loin d'être claire amha. J'ai dû tatoner pas mal avant d'avoir un code fonctionnel.

    As-tu bien un projet Python qui compile correctement et que tu arrives à linker ? C'est assez difficile, perso j'ai du modifier les sources, trouver les flags de compil etc avant d'y parvenir..
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    et merci à toi.

    Alors tout d'abord, chose importante, je suis un grand débutant en C++. J'ai galéré comme pas possible pour trouver un "bon" tutoriel qui parte d'une hypothèse simple : le lecteur n'ai jamais programmé quoique ce soit de sa vie. Heureusement j'ai pu trouver celui-ci durant mes vacances.

    Citation Envoyé par Bousk Voir le message
    Salut,

    Tu devrais plutôt t'attarder sur cet exemple simple : http://docs.python.org/3/extending/e...evel-embedding
    Le pure embedding a peu d'intérêt amha, l'essentiel étant à priori l'utilisation de http://docs.python.org/3/c-api/veryh...n_SimpleString pour réaliser import et appel de méthodes Python depuis le C++.
    Je suis effectivement déjà tombé sur le lien que tu donnes, et cette simplicité me plaisait bien, mais je rencontre aussi quelques problèmes avec cette façon de faire.

    D'ailleurs, je suis obligé de modifier le code comme ceci si je ne veux pas avoir d'erreur :
    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
    main(int argc, wchar_t *argv[]) // remplace de char par wchar_t
    {
      Py_SetProgramName(argv[0]);  /* optional but recommended */ //ou il faut que je commente cette ligne.
      Py_Initialize();
      PyRun_SimpleString("from time import time,ctime\n"
                         "print('Today is', ctime(time()))\n");
      Py_Finalize();
      return 0;
    }
    Citation Envoyé par Bousk Voir le message
    S'il s'agit d'appeler des méthodes d'un script .py depuis le C++ c'est plus simple que l'inverse, mais l'initialisation de Python est un peu obscure et la doc loin d'être claire amha. J'ai dû tatoner pas mal avant d'avoir un code fonctionnel.
    En fait le but de mes recherches est assez simple (et j'espère possible ). Je suis actuellement en train de réaliser une application en PyQt et Qt Quick. Elle avance bien et reste une application assez simple :
    • une interface graphique de saisie de données ;
    • une injection dans une base de données PostgreSQL ;
    • la possibilité de consulter et modifier les données ;


    Actuellement je teste tout sur ma Debian, j'ai donc toutes les bibliothèques, etc et je n'ai pas de souci. Cependant je prévois de mettre à disposition à certains collègues cette application, et se pose donc le "problème" de la distribution. Le souci est que rendre la version actuelle (PyQt + Qt Quick) standalone risque d'être fort compliqué, idem pour distribuer Python, les sources et les bibliothèques nécessaires. Je pense avoir moins de problèmes avec C++ (enfin j'espère ).

    L'avantage de Qt Quick est que dans l'immédiat une très grosse partie du travail est déjà faite par QML et en fait la partie "Python" ne me sert qu'à lancer le programme et travailler sur les données, chaînes de caractères, ...

    Mon idée est donc la suivante :
    1. je crée un bout de code C++ histoire de pouvoir dans un premier rendre son lancement "standalone" (pas son fonctionnement en profondeur) ça m'a pris 5min... Impec ;
    2. je recode les manipulations de chaînes qui peuvent être très simples, etc ;
    3. j'embarque Python dans mon code C++ et réutilise les fonctions un peu longue ou plus complexe à faire en C++ dans un premier temps histoire de ne pas me prendre la tête.
    .

    Voila pour le but de tout ça ...

    Citation Envoyé par Bousk Voir le message
    As-tu bien un projet Python qui compile correctement et que tu arrives à linker ? C'est assez difficile, perso j'ai du modifier les sources, trouver les flags de compil etc avant d'y parvenir..
    Si je reprends le lien que tu as donnés plus haut, voici où j'en suis :
    Cas 1 :
    test.py
    main.cpp
    Code : 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 <Python.h>
    #include <fstream>
    #include <string>
    #include <stdio.h>
    #include <iostream>
     
    using namespace std;
     
    int main(int argc, char *argv[])
    {
      //Py_SetProgramName(argv[0]);  /* optional but recommended */
      Py_Initialize();
     
      /*PyRun_SimpleString ne semble fonctionner que pour des imports de modules présents dans Python.
       C'est à dire pas pour ceux que je peux créer*/
     
      cout << "Essai d'import d'un module python livré d'origine via PyRun_SimpleString" << endl << "Début du test N°1" << endl;
      PyRun_SimpleString ("import os\n"
                         "print(os.getcwd())");
      cout << "Fin du test\n" << endl;
     
     
      cout << "Essai d'import d'un module python créé par moi via PyRun_SimpleString" << endl << "Début du test N°2" << endl;
      PyRun_SimpleString ("import test");
      cout << "Fin du test\n" << endl;
     
      cout << "Essai d'import d'un module python créé par moi via PyRun_SimpleFile" << endl << "Début du test N°3" << endl;
      FILE *pFile;
      pFile = fopen ("test.py","r");
     
      PyRun_SimpleFile(pFile,"test.py");
      cout << "Fin du test\n" << endl;
     
      Py_Finalize();
      return 0;
    }
    test1.pro
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SOURCES += main.cpp
     
    LIBS += -L /usr/lib/python3.3/config-3.3m-x86_64-linux-gnu -lpython3.3
    INCLUDEPATH += -I /usr/include/python3.3m/
    Chez moi les tests N° 1 & 3 fonctionnent bien. Pas le N° 2.
    Je ne vois pas non plus comment déclarer dans le test 3 la fonction ou la classe que je veux utiliser.

    J'en reviens donc au même point que l'exemple que j'ai cité au début du fil : importer un fichier *.py, pas de souci, mais je galère pour utiliser un "vrai" script.

    Une dernière chose, je travaille avec Qt Creator. Je compile aussi avec ce dernier par définition. Je n'ai strictement rien modifié dans les commandes de compilation. Par contre mon .pro est, actuellement purement identique à ce que je t'ai donné.
    Donc un problème de flags est très possible....

    En tout cas, merci de ton aide donnée et à venir.

    ++

    J
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Salut

    Citation Envoyé par Jiyuu Voir le message
    Actuellement je teste tout sur ma Debian, j'ai donc toutes les bibliothèques, etc et je n'ai pas de souci. Cependant je prévois de mettre à disposition à certains collègues cette application, et se pose donc le "problème" de la distribution. Le souci est que rendre la version actuelle (PyQt + Qt Quick) standalone risque d'être fort compliqué, idem pour distribuer Python, les sources et les bibliothèques nécessaires. Je pense avoir moins de problèmes avec C++ (enfin j'espère ).
    Si ton problème est la distribution de ton application, la coller dans un exécutable C++ est vraiment une très mauvaise idée, et en particulier si tu n'es pas familier voir bon connaisseur de C++. Tu vas créer un monstre de complexité pour un bénéfice quasi nul.

    Si tu as des contraintes fortes sur les versions de python et des bibliothèques pour que tes collègues puissent utiliser ton application, une bonne idée serait d'utiliser virtualenv. Ce sera plus facile de coder un installeur qui met en place un virtualenv fonctionnel avec ton appli dedans plutôt que de construire une sorte bouzin all inclusive en C++ .

  5. #5
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Re,

    Merci pour ta contribution jblecanard.
    J'ai entendu parlé de virtualenv que très récemment et je crois même avoir vu ici ou là qu'il était inclus d'office avec Python 3 (mais je ne préfère pas trop m'avancer de ce coté )

    Je me doute que la solution que je prévois est loin d'être optimum, mais elle a quelques avantages :
    • c'est un bon sujet d'apprentissage ;
    • ça me permet de tâter du C++ ;
    • ça peut m'ouvrir la porte à une migration complète du code en C++, ou pas .


    Comme je l'ai dit, le plus gros du programme est fait actuellement avec QML, j'ai donc peu de chose à coder (pour le moment) en Python ou C++, ce qui pourrait limiter la "lourdeur" du projet comme je voulais faire.

    Mais je vais potasser virtualenv... s'il y a plus simple, je ne suis pas non plus sado

    Pour revenir à mon problème, j'ai trouvé la solution. C'est presque une histoire de flags... en faite dans mon cas il faut systématiquement rajouter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PyRun_SimpleString("import sys; sys.path.append('.')");
    après
    C'est tout bête, mais je n'ai pas vu ça dans la doc... dommage.

    Du coup tous les tests que j'ai donné ci-dessus fonctionnent.

    Et pour les imports de fonction, il suffit de déclarer plusieurs Py_SimpleString :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <Python.h>
     
    int main() {
        Py_Initialize();
        PyRun_SimpleString("import sys; sys.path.append('.')");
        PyRun_SimpleString("from mytest import fctTest2");
        PyRun_SimpleString("fctTest2()");
        Py_Finalize();
     
        return 0;
    }
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    En fait c'est parce que ajouter "." dans sys n'a strictement rien à voir avec l'embedding, c'est du pur "hack" Python.
    Pour importer un script, il faut savoir où le trouver. Tout simplement
    Cet artifice est fait via le python.exe, mais il faut le faire toi-même dans ton exe.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre chevronné
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Par défaut
    Citation Envoyé par Jiyuu
    En fait le but de mes recherches est assez simple (et j'espère possible ). Je suis actuellement en train de réaliser une application en PyQt et Qt Quick. Elle avance bien et reste une application assez simple :
    • une interface graphique de saisie de données ;
    • une injection dans une base de données PostgreSQL ;
    • la possibilité de consulter et modifier les données ;


    Actuellement je teste tout sur ma Debian, j'ai donc toutes les bibliothèques, etc et je n'ai pas de souci. Cependant je prévois de mettre à disposition à certains collègues cette application, et se pose donc le "problème" de la distribution. Le souci est que rendre la version actuelle (PyQt + Qt Quick) standalone risque d'être fort compliqué, idem pour distribuer Python, les sources et les bibliothèques nécessaires. Je pense avoir moins de problèmes avec C++ (enfin j'espère ).
    Et faire un « exécutable » Python via cx_freeze, ça ne répondrait pas à ton problème de distribution ?
    Je sais que cx_freeze fonctionne avec Python 2 et 3 et qu’il n’y a pas de soucis pour embarquer PyQt (il y a ici un exemple un peu vieux)

  8. #8
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par grim7reaper Voir le message
    Et faire un « exécutable » Python via cx_freeze, ça ne répondrait pas à ton problème de distribution ?
    Je sais que cx_freeze fonctionne avec Python 2 et 3 et qu’il n’y a pas de soucis pour embarquer PyQt (il y a ici un exemple un peu vieux)


    J'y ai pensé effectivement, mais je sais pas.... une intuition me fait dire qu'avec Qt Quick ça allait merdouiller, et j'ai l'impression que mon intuition était pas si folle que ça : http://www.riverbankcomputing.com/pi...ry/033629.html.

    Mais ça mériterait de se pencher vraiment dessus c'est certain.
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  9. #9
    Membre chevronné
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Par défaut
    Arf’, en effet ^^"
    Bah espérons que ça soit rapidement résolu alors.
    Car ça reste quand même la solution la plus simple je pense.

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

Discussions similaires

  1. Appel de fonction/script python via PHP
    Par rastalien dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 21/02/2008, 18h12
  2. Intégrer un script python dans une page Web
    Par Mysti¢ dans le forum Réseau/Web
    Réponses: 4
    Dernier message: 02/11/2006, 10h20
  3. [VBS] appel d'un script VBS dans un autre script VBS???
    Par Amandine62 dans le forum VBScript
    Réponses: 9
    Dernier message: 31/01/2006, 18h17
  4. Interpreter un script python dans un prog python
    Par romeo9423 dans le forum Général Python
    Réponses: 3
    Dernier message: 01/12/2005, 16h16
  5. Appel d'un script SQL dans une procdure stockée
    Par doudou10000 dans le forum Oracle
    Réponses: 10
    Dernier message: 01/12/2004, 10h01

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