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 :

[C++Python] Passer une instance C++ à un script Python


Sujet :

C++

  1. #1
    Membre confirmé
    Homme Profil pro
    Consultant MOA
    Inscrit en
    Juillet 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant MOA
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2004
    Messages : 289
    Points : 635
    Points
    635
    Par défaut [C++Python] Passer une instance C++ à un script Python
    Bonjour à tous,

    Comme je ne sais pas ou poster je l'ai mis ici

    J'essaie de passer une instance d'une classe C++ vers un script Python
    J'ai définie la classe en python en utilisant Boost.
    J'arrive à récupérer un ojbet de python, mais je n'arrive pas à envoyer un objet (instance) dans un script

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
        * #include <iostream>
        * #include <fstream>
        * #include <string>
        * using namespace std;
        *
        * #include <boost/python.hpp>
        * #include <graminit.h>
        * using namespace boost::python;
        *
        * // Classe "Base" C++
        * class Base
        * {
        * public:
        *     Base(int iPoids = 0) {_Poids = iPoids;};
        *     ~Base() {};
        *     int GetPoids() {return _Poids;};
        *     void SetPoids(int iPoids) {_Poids = iPoids;};
        * private:
        *     int _Poids;
        * };
        *
        * // Classe "Base" Python
        * BOOST_PYTHON_MODULE(DIP)
        * {
        *    class_<Base>("Base", init<int>())
        *         .def("GetPoids", &Base::GetPoids)
        *         .def("SetPoids", &Base::SetPoids)
        *     ;
        * }
        *
        * string *readPythonScript( string fileName ); // fonction implémentée et qui marche, non explicité ici
        *
        * //-----------------------------------------------------------------------------
        * // Name: main()
        * // Desc: Application's main entry point.
        * //-----------------------------------------------------------------------------
        * void main( void )
        * {
        *     
        *     Base Agent; // j'aimerais passer Agent dans le script
        *
        *     if( PyImport_AppendInittab( "DIP", initDIP ) == -1 )
        *         throw runtime_error( "Failed to add \"DIP\" to the "
        *                              "interpreter's built-in modules" );
        *
        *     // Setup Python to be embedded...
        *     Py_Initialize();
        *
        *     object main_module(( handle<>(borrowed(PyImport_AddModule("__main__")))));
        *     object main_namespace = main_module.attr("__dict__");
        *
        *     string *pythonScript = readPythonScript( "test.py" );
        *
        *     if( pythonScript != NULL )
        *     {
        *         PyRun_String( pythonScript->c_str(), Py_file_input,
        *                       main_namespace.ptr(), main_namespace.ptr() );
        *     }
        *
        *     delete pythonScript;
        *
        *     Agent = extract<Base&>(main_namespace["Agent"]); //Récup de l'instance agent du script dans l'objet C++
        *     cout << "Agent: " << Agent.GetPoids() << endl;
        *
        *     // Cleanup after Python...
        *     Py_Finalize();
        *
        *     system("pause");
        * }
    et le script
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        * from DIP import *
        *
        * //Agent = Base(10) il faudrait récupérer l'instance Agent du c++
        * Agent.SetPoids(15)
    Quelqu'un connaitrait-il le contraire de "extract" ? (genre intract ou insert )

    Pitié j'ai besoin d'aide
    Merci d'avance

  2. #2
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 669
    Points
    10 669
    Billets dans le blog
    3
    Par défaut
    Avec boost je sais pas, mais moi je l'ai fait avec swig.

  3. #3
    Membre confirmé
    Homme Profil pro
    Consultant MOA
    Inscrit en
    Juillet 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant MOA
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2004
    Messages : 289
    Points : 635
    Points
    635
    Par défaut
    Le problème est que dans le projet on utilise Boost, et je sais presque tout faire avec Boost:ython sauf insérer une instance d'objet dans le main_module de Python

    C'est pour ça que si quelqu'un sait comment faire avec Boost, je suis preneur

    Merci d'avance

  4. #4
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 669
    Points
    10 669
    Billets dans le blog
    3
    Par défaut
    D'après ce que je me souviens, faut créer une dll avec un fichier .py qui décrit la classe qu'il y a dedans, et depuis ta dll renvoyer des PyObject pour que l'interpréteur les comprenne.

  5. #5
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Points : 71
    Points
    71
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel Voir le message
    D'après ce que je me souviens, faut créer une dll avec un fichier .py qui décrit la classe qu'il y a dedans, et depuis ta dll renvoyer des PyObject pour que l'interpréteur les comprenne.
    C'est pas un peu compliqué ? Ca irait pas mieux si on créait une fonction qui renvoie l'instance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Base &get_instance(Base *inst = 0) // paramètre pour spécifier l'instance
    {
    	static Base* instance = 0; // faute d'inattention
    	if(inst != 0) instance = inst;
     
    	if(instance == 0) throw std::string("aucune instance disponible");
     
    	return instance;
    }
    On enregistre cette fonction dans le module grâce à boost.python.
    Cette fonction sera appelée par le c++ pour enregistrer l'instance, puis par le python pour la récupérer (normalement ça marche).

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Quel doit être le type de la variable instance ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1
    Points : 1
    Points
    1
    Par défaut il faut passer 'manage_new_object'
    Salut,

    Il faut passer le parametre 'manage_new_object' pour que Boost puisse passer la nouvelle instance à Python.
    Voici un example:

    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 <boost/python.hpp>
     
    using namespace boost::python;
     
    class Test {
    };
     
     
    Test* create()
    {
            return new Test();
    }
     
    BOOST_PYTHON_MODULE(test)
    {
        class_<Test>("Test");
        def("create", create, return_value_policy<manage_new_object>());
    }
    Le résultat depuis python:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    >>> import test
    >>> test.create()
    <test.Test object at 0x2b4598e46980>
    Voir aussi:
    http://wiki.python.org/moin/boost.python/FAQ

  8. #8
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Points : 71
    Points
    71
    Par défaut
    J'ai réfléchi et il y a un truc tout bête qui peut aller :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    main_module.attr("Agent") = boost::python::object(Agent);
    Essaye, on verra si ça marche.

Discussions similaires

  1. 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
  2. Réponses: 5
    Dernier message: 08/09/2006, 08h56
  3. Comment passer une variable jsp à un script ?
    Par MAJIK_ENIS dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 28/05/2006, 20h50
  4. Changer de base à l'intérieure d une instance dans un script
    Par Labienus dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 02/12/2005, 16h03
  5. Passer une variable C à un script en Javascript
    Par aquouel dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 21/09/2005, 17h41

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