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++

  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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    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

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 049
    Points
    33 049
    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..

  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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    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

  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
    Points : 3 159
    Points
    3 159
    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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    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;
    }

  6. #6
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 049
    Points
    33 049
    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.

  7. #7
    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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    Billets dans le blog
    15
    Par défaut
    Tu penses à quelques choses comme ça :
    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
    #include <Python.h>
     
     
    int main(int argc, wchar_t *argv[])
    {
        Py_SetProgramName(argv[0]);
        Py_Initialize();
     
        wchar_t *path = Py_GetPath();
        Py_SetPath(path);
     
     
        //PyRun_SimpleString("import sys; sys.path.append('.')");
        PyRun_SimpleString("from mytest import fctTest2");
        PyRun_SimpleString("fctTest2()");
        Py_Finalize();
     
        return 0;
    }
    Malheureusement ça me sort ça :
    Traceback (most recent call last):
    File "<string>", line 1, in <module>
    ImportError: No module named 'mytest'
    Traceback (most recent call last):
    File "<string>", line 1, in <module>
    NameError: name 'fctTest2' is not defined

  8. #8
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 049
    Points
    33 049
    Billets dans le blog
    4
    Par défaut
    Le sujet est-il résolu ou non ?
    Tu retombes sur une erreur Python, ton exe ne sait pas où trouver le fichier.

    Es-tu sûr de ce que tu passes à Py_SetProgramName ?

  9. #9
    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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Le sujet est-il résolu ou non ?
    Ben moi j'aimais bien ma solution de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PyRun_SimpleString("import sys; sys.path.append('.')")
    mais tu m’incites à trouver une meilleure soluce , donc disons que maintenant il est résolu à moitié (je détag )

    Citation Envoyé par Bousk Voir le message
    Tu retombes sur une erreur Python, ton exe ne sait pas où trouver le fichier.
    Il cherche pas beaucoup... il est juste à coté de lui, dans le même répertoire

    Citation Envoyé par Bousk Voir le message
    Es-tu sûr de ce que tu passes à Py_SetProgramName ?
    Alors là tu me pose une bonne colle... à priori la bébète ne renvoie rien (doc : void Py_SetProgramName(char *name)) donc je sais pas trop comment vérifier ceci.

    Par contre, venant de trouver comment lire en clair un wchar_t, je peux dire que j'ai effectivement un souci de path :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    wchar_t *path = Py_GetPath();
    std::wcout << path << std::endl;
    me renvoie :
    /usr/lib/python3.3/:/usr/lib/python3.3/plat-x86_64-linux-gnu:/usr/lib/python3.3/lib-dynload
    Je pourrais essayer de passer le répertoire courant dans Py_SetPath(), mais ça ne marche pas top à priori puisque :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    wchar_t *pathScript = L".";
    Py_SetPath(pathScript);
    ne me permet pas d'exécuter correctement le code python (même erreur que ci-dessus).

  10. #10
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 049
    Points
    33 049
    Billets dans le blog
    4
    Par défaut
    En fait si le fichier se trouve juste à côté de l'exe, c'est que l'appel à Py_SetProgramName ne doit pas être bon.
    Mais si la première astuce passe, autant la garder^^ sans le py_SetProgramName je n'étais pas sûr que ça passe.

  11. #11
    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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    Billets dans le blog
    15
    Par défaut
    Si jamais tu retrouves des traces de la manière que tu utilisais, ça m'intéresse tout de même au cas où

    EDIT :

    Et puis il me reste aussi à trouver le moyen de récupérer dans une variable C++ le return de ma fonction fctTest2() lorsque je fais :
    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;
    }

  12. #12
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 049
    Points
    33 049
    Billets dans le blog
    4
    Par défaut
    En fait c'est similaire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Py_SetProgramName(...);
    .. export de modules ici ..
    Py_SetPath(L"Py"); // les modules python classiques sont dans un dossier Py à coté de l'exe
    Py_Initialize();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('Scripts')"); // mes scripts sont dans un dossier Scripts à côté de l'exe
    Pour récupérer le résultat de l'appel d'une fonction Python, il faut utiliser PyObject_CallObject, PyObject_CallFunctionObjArgs et consors, mais pour créer le paramètre PyObject nécessaire, c'est pas forcément évident... peut-être t'y prends-tu juste mal, comment sais-tu quel callback python appelée ? Le C++ fournit-il une "SetCallback" pour l'initialiser ?

  13. #13
    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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par Bousk Voir le message
    En fait c'est similaire
    Ahhh ben tu me rassures

    Citation Envoyé par Bousk Voir le message
    Pour récupérer le résultat de l'appel d'une fonction Python, il faut utiliser PyObject_CallObject, PyObject_CallFunctionObjArgs et consors, mais pour créer le paramètre PyObject nécessaire, c'est pas forcément évident... peut-être t'y prends-tu juste mal, comment sais-tu quel callback python appelée ? Le C++ fournit-il une "SetCallback" pour l'initialiser ?
    Tu crois ????

    C'est même un sacré bazar en fait ...
    Le premier exemple que j'ai donné montre assez bien comment manipuler des nombres... je me suis intéressé aux strings.
    Voila mon dernier morceau de code :

    Code cpp : 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
    40
    41
    42
    43
    44
    45
    #include <Python.h>
    #include <iostream>
    #include <stdlib.h>
     
    using namespace std;
     
    string fctPython(char *pScript, char *pFunct, PyObject *pArgs);
     
     
    int main(int argc, char *argv[])
    {
        PyObject *pArgs1, *pArgs2, *pValue1_1, *pValue1_2;
        char *module = "myTest", *fct1 = "functString";
     
        Py_Initialize();
        PyRun_SimpleString("import sys; sys.path.append('.')");
     
        /*Essai de functString*/
        pArgs1 = PyTuple_New(2);
     
        pValue1_1 = PyBytes_FromFormat("%s","functString : ceci est l'essai n°");
        PyTuple_SetItem(pArgs1, 0, pValue1_1);
     
        pValue1_2 = PyBytes_FromFormat("%i",1);
        PyTuple_SetItem(pArgs1, 1, pValue1_2);
     
        string resultat1 = fctPython(module, fct1, pArgs1);
        cout << resultat1 << endl;
     
        Py_Finalize();
        return 0;
    }
     
    string fctPython(char *pScript, char *pFunct, PyObject *pArgs)
    {
        PyObject *pName, *pModule, *pFunc, *pValue;
     
        pName = PyUnicode_FromString(pScript);
        pModule = PyImport_Import(pName);
        pFunc = PyObject_GetAttrString(pModule, pFunct);
     
        pValue = PyObject_CallObject(pFunc, pArgs);
     
        return PyBytes_AsString(pValue);
    }

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def functString(a, b):
        w = ", avec essai d'une phrase écrite dans le script python"
        v = w.encode(encoding='UTF-8')
        print (type(a), type(b), type(v))
        c = a + b + v 
        return c

    Il y a pas mal de choses sympa à faire mais ça demande vraiment pas mal de recherche, trop de recherche en fait... et je mesure mieux la remarque de jblecanard : Tu vas créer un monstre de complexité

    Le sujet est vraiment vaste et intéressant, mais ça manque vraiment de doc et de fonctions plus proche de l'esprit Python : faire en peu de lignes des choses simples et moins simples aussi.

    Pour revenir à mon problème initial, outre la distribution, passer mon programme en C++ me permettrait de bénéficier plus rapidement des avancées de Qt notamment celles liées à Qt Quick qui s'enrichit de jour en jour. À titre d'exemple, la version Qt dans mes dépôts étant la version 5.1.1, je n'ai pas réussi à bénéficier pleinement de la version 5.2 de PyQt, alors que j'ai bien la version 5.2 de Qt (installée depuis les binaires), faudrait d'ailleurs que je me penche là-dessus.

    Et puis il faut bien l'avouer, depuis le temps que j'ai tenté de commencer à envisager l'apprentissage de C++, je vais pas m'arrêter en si bon chemin ... faut juste que je rebosse à fond les pointeurs car c'est encore un peu obscure pour moi c'te bête.

    Donc je pense que le plus raisonnable serait de continuer tranquilou mon programme en Python et en parallèle le transcrire en C++, et si jamais je tombe sur une fonction vraiment casse bonbon à faire en C++ mode bourrin : je lance la fonction Python avec PyRun_SimpleString et comme j'ai pas encore trouvé comment récupérer le résultat , je stock ce dernier dans un fichier que je récupère en C++ après...

    Merci à vous deux en tout cas, et si vous o d'autres ont des remarques n'hésitez pas

    ++

    J

  14. #14
    Membre émérite
    Inscrit en
    Avril 2010
    Messages
    1 495
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 1 495
    Points : 2 274
    Points
    2 274
    Par défaut
    Salut,

    Juste pour dire que si tu veux vraiment apprendre le C++ apprends-le à fond, c'est tout sauf perdu.

  15. #15
    Membre éclairé
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Points : 870
    Points
    870
    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)

  16. #16
    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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    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.

  17. #17
    Membre éclairé
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Points : 870
    Points
    870
    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.

  18. #18
    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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    Billets dans le blog
    15
    Par défaut
    Bon ben du coup tu m'as poussé à tester et effectivement ça merdouille...Déjà à l'installationuntu-fr.org/viewtopic.php?pid=15346621"]Déjà à l'installation[/URL] de cx_Freeze en ce qui me concerne, et ensuite à l'exécution.

    J'ai une autre piste en utilisant cython... j'ai déjà réussi à créer un exécutable avec mais je n'ai pas eu l'occasion de tester sur une autre machine et en plus il y a un morceau de commande que je n'arrive pas à retrouver

  19. #19
    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
    Points : 3 159
    Points
    3 159
    Par défaut
    Citation Envoyé par Jiyuu Voir le message
    Donc je pense que le plus raisonnable serait de continuer tranquilou mon programme en Python et en parallèle le transcrire en C++
    Oui

    Citation Envoyé par Jiyuu Voir le message
    Donc je pense que le plus raisonnable serait de continuer tranquilou mon programme en Python et en parallèle le transcrire en C++, et si jamais je tombe sur une fonction vraiment casse bonbon à faire en C++ mode bourrin : je lance la fonction Python avec PyRun_SimpleString et comme j'ai pas encore trouvé comment récupérer le résultat , je stock ce dernier dans un fichier que je récupère en C++ après...
    Non, c'est mal, surtout que tu vas rencontrer ce problème inévitablement, vu la richesse de la lib standard de Python. Et comme tu dans une saine démarche d'apprentissage, il vaut mieux rester rigoureux, surtout avec C++ qui est un langage exigeant.

    Citation Envoyé par minnesota Voir le message
    Juste pour dire que si tu veux vraiment apprendre le C++ apprends-le à fond, c'est tout sauf perdu.
    Entièrement d'accord.

    Note aussi que lorsque tu fais des bricoles ou tu échanges des données entre C++ et un autre langage, il faut faire attention à la gestion de la mémoire. Un petit coup de valgrind sur ton prototype existant risque de révéler quelques surprises !

  20. #20
    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 : 42
    Localisation : France, Loire (Rhône Alpes)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Points : 6 789
    Points
    6 789
    Billets dans le blog
    15
    Par défaut


    Merci pour tous ces conseils.
    Concernant mon apprentissage de C++, je reste pour le moment bien bloqué sur les pointeurs et références et surtout leur utilité !!! z'êtes tordus les gars

    J'ai voulu mettre la charrue bien avant les bœufs en essayant de chercher un moyen de lancer du python via C++... on va reprendre tout ceci dans l'ordre.

    Encore merci à tous.

+ 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