Partage
  • Partager sur Facebook
  • Partager sur Twitter

Combiner du C++ et du Python

    9 août 2019 à 15:08:20

    Salut,

    J'ai pour projet de développer une application sous Windows. J'utilise actuellement Qt pour Python pour le développement de la partie graphique de l'app. J'ai intégré quelques fonctionnalités que j'ai développés en Python mais je trouve certains points du programme assez lent. Je souhaite donc combiner mes scripts Python avec du C++ pour gagner quelques secondes d’exécutions et rendre le programme plus fluide.  Je ne sais pas par où commencer. Dois je développer entièrement l'interface graphique en C++ sous Qt et appeler les scripts Python qui me sont nécessaire (utilisation de Matplotlib par exemple) ? Ou développer toute l'interface en Python et appeler les fonctions en C++ qui seront susceptibles d'améliorer la vitesse d’exécution ?

    Merci,

    -
    Edité par zaki95 9 août 2019 à 15:08:48

    • Partager sur Facebook
    • Partager sur Twitter
      9 août 2019 à 15:25:21

      Je n'ai jamais fait , mais selon moi apeller du python dans un code c++ est plus facile que l'inverse.
      • Partager sur Facebook
      • Partager sur Twitter
        9 août 2019 à 15:31:01

        ?

        L'utilisation typique est de coder les briques de calcul dans des langages compilés et propices aux optimisations, et de les gluer dans un langage de glue. Python quoi.

        Après, il existe divers framework qui facilitent l'interopérabilité. Le dernier qui m'a marqué (non testé) est: https://pybind11.readthedocs.io/en/master/

        • Partager sur Facebook
        • Partager sur Twitter
        C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
          9 août 2019 à 15:42:30

          Zérotisme a écrit:

          Je n'ai jamais fait , mais selon moi apeller du python dans un code c++ est plus facile que l'inverse.


          Ça me parait pas mal. Par contre ça me semble un peu compliqué à déployer sur une autre machine. Il faut donc obligatoirement installer l'interpréteur Python et l'ajouter au Path sur chaque machine ? Et comment masquer les scripts pour qu'ils ne soient ni visible et ni modifiable par l'utilisateur ?

          lmghs a écrit:

          ?

          L'utilisation typique est de coder les briques de calcul dans des langages compilés et propices aux optimisations, et de les gluer dans un langage de glue. Python quoi.

          Après, il existe divers framework qui facilitent l'interopérabilité. Le dernier qui m'a marqué (non testé) est: https://pybind11.readthedocs.io/en/master/

          Je connaissais pas du tout, je vais y jeter un œil merci.

          • Partager sur Facebook
          • Partager sur Twitter
            9 août 2019 à 15:54:32

            > Et comment masquer les scripts pour qu'ils ne soient ni visible et ni modifiable par l'utilisateur ?

            En utilisant uniquement un langage compilé :D

            PS: appeler du Python depuis du C++ ne me parait pas le plus simple. Bien au contraire.

            • Partager sur Facebook
            • Partager sur Twitter
            C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
              9 août 2019 à 19:48:44

              lmghs a écrit:

              > Et comment masquer les scripts pour qu'ils ne soient ni visible et ni modifiable par l'utilisateur ?

              En utilisant uniquement un langage compilé :D

              PS: appeler du Python depuis du C++ ne me parait pas le plus simple. Bien au contraire.


              Je dois donc faire une croix sur Python si je veux que mon programme soit entièrement protégé de toute lecture/écriture ? Si je me contente que du C++ je sent que je vais bien galérer :(

              • Partager sur Facebook
              • Partager sur Twitter
                9 août 2019 à 20:54:28

                Pas forcément, tu peux "embarquer" un interpréteur Python dans ton programme C++, et lui passer les scripts sous forme de buffer mémoire que tu auras préalablement chargé. Dès lors, rien ne t'empêche de chiffrer tes scripts Python (ton programme C++ les charge,puis les déchiffre), tu résous le problème de visibilité et ils ne sont plus modifiables facilement (il faut les déchiffrer, les modifier, puis les rechiffrer, pour que ton programme les accepte). Il y a un autre avantage, tu peux rendre l'étape de chiffrement/déchiffrement optionnelle (via par exemple un define), ainsi tu peux te construire une version qui ne gère pas le chiffrement, que tu utiliseras pour la mise au point de ton programme et de tes scripts, et une version qui le gère pour les utilisateurs. Pour le chiffrement, pas besoin d'un truc de qualité militaire, un xor sur une clé en dur suffira à décourager presque tout le monde ;) et puis si tu as besoin, d'un truc plus costaud, tu as de très bonnes bibliothèques C/C++ qui font ça très bien avec les algos de chiffrement les plus avancés du marché (OpenSSL par exemple).

                -
                Edité par int21h 9 août 2019 à 21:14:33

                • Partager sur Facebook
                • Partager sur Twitter
                Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                  9 août 2019 à 22:45:34

                  int21h a écrit:

                  Pas forcément, tu peux "embarquer" un interpréteur Python dans ton programme C++, et lui passer les scripts sous forme de buffer mémoire que tu auras préalablement chargé. Dès lors, rien ne t'empêche de chiffrer tes scripts Python (ton programme C++ les charge,puis les déchiffre), tu résous le problème de visibilité et ils ne sont plus modifiables facilement (il faut les déchiffrer, les modifier, puis les rechiffrer, pour que ton programme les accepte). Il y a un autre avantage, tu peux rendre l'étape de chiffrement/déchiffrement optionnelle (via par exemple un define), ainsi tu peux te construire une version qui ne gère pas le chiffrement, que tu utiliseras pour la mise au point de ton programme et de tes scripts, et une version qui le gère pour les utilisateurs. Pour le chiffrement, pas besoin d'un truc de qualité militaire, un xor sur une clé en dur suffira à décourager presque tout le monde ;)et puis si tu as besoin, d'un truc plus costaud, tu as de très bonnes bibliothèques C/C++ qui font ça très bien avec les algos de chiffrement les plus avancés du marché (OpenSSL par exemple).

                  -
                  Edité par int21h il y a environ 1 heure


                  Je n'y ai pas pensé au coup du buffer, ca me semble être une excellente idée.. Par contre je ne risque pas d'être emmerder avec la syntaxe de python qui prend en compte les tabulations ?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    10 août 2019 à 16:04:38

                    salut

                    Je n'y ai pas pensé au coup du buffer, ca me semble être une excellente idée.. Par contre je ne risque pas d'être emmerder avec la syntaxe de python qui prend en compte les tabulations ?

                    Ben non, pourquoi le serais tu ? comment crois tu que l'interpréteur de python fonctionne ?

                    Tu sais, il n'y a que très peu de différence entre une fichier et une  entrée clavier (du moins, en C++): car ce sont deux classes qui dérivent de std::istream (en  fait : std::basic_istream, mais bon ... c'est un détail ;) ) :

                    • une entrée clavier est fournie par l'utilisateur de l'ordinateur, alors qu'un fichier fourni le même contenu, mais issue d'une sauvegarde sur le disque dur
                    • les fichiers vont -- naturellement -- nécessiter "un certains temps" pour récupérer les données qu'ils contiennent (plus que si elles sont déjà en mémoire, va-t-on dire), alors qu'une entrée clavier va dépendre de l'habitude que l'utilisateur a pour l'utilisation de son clavier, et de la vitesse à laquelle il sera capable d'écrire avec celui-ci (je suis capable d'écrire avec mes dix doigts à peu près 50 mots de 8 lettres à la minute, sans regarder le clavier, mais d'autres vont devoir regarder leur clavier pour chercher chaque touche, et ne pourront écrire que  un ou deux  mots de 8 lettres à la minute :D )

                    Bien sur, tu ne dois pas utiliser l'opérateur >> pour récupérer la ligne de ton fichier (ou l'entrée de l'utilisateur), mais plutôt la fonction std::getline (istream &, std::string &), pour que chaque ligne soit prise "dans son ensemble", mais, pour le reste, ce sera exactement "du pareil au même" ;)

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                      16 août 2019 à 11:37:49

                      En gros, tu vas avoir 3 fonctions, une qui charge le fichier contenant le script, une qui le déchiffre, et une pour exécuter le script déchiffré. Ca va te donner quelque chose qui va ressembler à ça:

                      using Buffer = std::vector<char>;
                      
                      Buffer loadScript(fs::path const & fileName);
                      
                      Buffer uncrypt(Buffer const & data,CRYPTO_CONTEXT const & context);
                      
                      void execScritp(Buffer const & script,PYTHON_CONTEXT & context);
                      
                      int main()
                      {
                          try{
                      
                               auto buffer = loadScript(myScript);
                      
                      #if !defined(DEV_VERSION)
                               auto crypto = acquireCryptoContext();
                               buffer = uncrypt(buffer,crypto);
                      #endif // !defined(DEV_VERSION)
                      
                               auto python = acquirePythonContext();
                               execScript(buffer,python);
                      
                          } catch(std::exception const & e) {
                      
                              std::cerr << "Error on script " << myScript << ":" << e.what() << std::endl;
                      
                          }
                          return 0;
                      }
                      

                       fs::path est un type censé contenir un chemin, typiquement ce sera un std::filesystem::path, un boost::filesystem::path ou au pire un std::string.

                      CRYPTO_CONTEXT et PYTHON_CONTEXT vont correspondre aux éléments nécessaires pour le déchiffrement (CRYPTO_CONTEXT) et ensuite l'exécution du script dans l'interpréteur embarqué(PYTHON_CONTEXT), ça dépendra donc des bibliothèques que tu vas utiliser.

                      Là je gère les erreurs par exception (en C++, c'est souvent plus pratique de les gérer comme ça). Bien sûr, ici on a une gestion vraiment minimale (voir quasiment inutile), dans un vrai programme le catch serait plus conséquent.

                      -
                      Edité par int21h 16 août 2019 à 11:49:37

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug

                      Combiner du C++ et du Python

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown