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 :

utiliser un pointeur en python


Sujet :

Interfaçage autre langage Python

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 101
    Points : 75
    Points
    75
    Par défaut utiliser un pointeur en python
    bonjour,

    je programme un jeu en c++ et j'ai besoin d'ajouter des script pour personnaliser certaines actions.

    dans mon code c++, je déclare
    et j'appelle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int val = boost::python::call<int>(Func,boost::python::ptr(&player1));
    dans ma fonction, quand je lis simplement la valeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def func(player):
        c = player.life * 2
        return c
    tout se passe correctement

    mais j'aimerais pouvoir modifier la valeur de player.life :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def func(player):
        c = player.life * 2
        player.life = 200
        return c
    mais quand je lance ce code, le code refuse de se compiler correctement.
    que puis-je faire?

    merci,
    delfare

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 11
    Points : 14
    Points
    14
    Par défaut
    [Edit] J'ai trouvé une doc digne de ce nom là:

    http://www.boost.org/doc/libs/1_36_0...reference.html

    à ta place je ferais donc ceci


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    using namespace python::boost;
    ...
    Player player 1;
    int val = call<int>(func, ptr <Player> (player1));
    car : C++ est sensible à la casse
    boost:python::ptr attend un pointeur sur un objet de classe connue (fournie en paramètre) , pas, l'adresse d'un objet (autrement dit ptr déreferrence son arguement et accède à ses propriétés d'aprés la classe passée en paramètre. Si tu le ne lui passes qu'une referrence, bin ça ne suffira pas : "comment va t il deviner la classe ou le type des données passées en arguement, notre brave compileur C++, hein ?").

    Et voilà la doc concernant ptr "expensive_to_copy" étant bien sur une classe.

    http://www.boost.org/doc/libs/1_36_0....html#ptr-spec
    ps : ton soucis c'est du c++ pas du python, elle est toute simple ta fonction python : mauvais forum

    ps2 : bon bin, mon jeune padawan kamikaze, il ne faut pas t'attaquer à boost::python tout seul et désarmé : va donc chercher ta côte de mailles intégrale là (oui c'est en anglais, si tu comptes utiliser des librairies telles que boost::python -- dont la doc officielle est en anglais -- il te faudra aussi maîtriser la langue de shakespeare).
    http://www.cplusplus.com/doc/tutorial/

    N'oublions pas non plus : que ce que tu nous a filé, ne fonctionne pas, avec un compilateur descent :
    Player player1;
    créé un pointeur NULL sur un objet de classe Player. si tu tentes de passer un pointeur NULL et de le déréferrencé avec l'opérateur d'indirection "." (en python), python devrait te dire qu'il ne trouve pas la propriété life.
    player1 n'est pas un objet, mais un pointeur sur un objet donc &player1 est l'adresse de ton pointeur null (dont le contenu est null : notre pointeur possède une adresse mais n'en contient pas). Tel que tu nous le montre sans fournir le type requis par le template de fonction boost::python::ptr (ou fonction générique). ça ne peut en aucun cas fonctionner donc Si tu veux plus d'infos : files nous le code complet. Apparement tu n'as pas fais ce jeux tu essayes de le comprendre ou de le modifier : c'est une bonne chose (encore que, le niveau te dépasse) mais files nous tout le code qu'on puisse te l'expliqué.

    Enfin Java c'est cool (pas de pointeurs, aucune allocation statique possible pour les objets, cohérence et parcimonie des librairies -- quelques librairies pour un domaine d'utilisation donné : en c++ t'as générallement 50 librairies par fonction souhaité et peu/pas de framework, c'est à dire de librairie thématique couvrant des domaines : interface graphique / protocole réseaux/ gestion de flux ... --). Python l'est encore plus (typage dynamique ) Donc utilises C++ (la machine de guerre des programmeurs chevronnés) si c'est absoluement nécessaire. Sinon, t'as plus simple comme langage.

  3. #3
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Citation Envoyé par yves_982
    N'oublions pas non plus : que ce que tu nous a filé, ne fonctionne pas, avec un compilateur descent :
    Player player1;
    créé un pointeur NULL sur un objet de classe Player
    Désolé, ça ne crée pas un pointeur NULL , ça fait directement un appel au constructeur de la classe Player, donc on a bel et bien un objet

    Sinon, delfare, tu peux nous montrer la classe Player? Et quel est l'erreur quand tu compiles?

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 11
    Points : 14
    Points
    14
    Par défaut
    eh non, ça ne fait pas appel au constructeur, il faut instancier les objets soi même ^^ essayes donc ça pour t'en convaincre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    using namespace std;
    #include <string>
     
    string s;
    s.replace("","joe était là");
    résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    yves@yves:~$ gcc test.cpp
    test.cpp:5: erreur: expected constructor, destructor, or type conversion before «.» token
    Voilà. Traduction Null Pointer Exception (en plus "poli" c'est pas une exception, c'est détecté à la compilation ici) et ça ne compile pas.

  5. #5
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Révises bien ton C++

    Démonstration:
    Code 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
     
    #include <iostream>
     
    class MaClasse
    {
    public:
        MaClasse()
        {
            std::cout << "Le voilà l'appel au constructeur, convaincu?\n";
        }
    };
     
    int main()
    {
        MaClasse belEtBienUnObjet;
        return 0;
    }
     
    // Résultat:
    //    Le voilà l'appel au constructeur, convaincu?

    Pour créer un pointeur NULL, on fait: Player* player1 = NULL;

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 101
    Points : 75
    Points
    75
    Par défaut
    finalement, l'erreur était tout autre et très stupide : j'ai généré par erreur des espaces au lieu d'une tabulation quand j'ai rajouté la ligne donc le décalage n'était plus correct et ça faisait rater la compilation

    donc, finalement, en déclarant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Player
    {
        public:
        Player(){life=100;}
     
        int life;
    };
    puis, en appelant pour le déclarer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    boost::python::class_<Player>("player", boost::python::init<>())
            .def_readwrite("life", &Player::life)
        ;
    je peux ensuite utiliser boost::python::ptr(&player1) et ça fonctionne parfaitement.

    ps : ton soucis c'est du c++ pas du python, elle est toute simple ta fonction python : mauvais forum
    désolé, je pensais que le forum python était le bon étant donné que c'est un problème lié à l'utilisation de python dans un autre langage

    ps2 : bon bin, mon jeune padawan kamikaze, il ne faut pas t'attaquer à boost::python tout seul et désarmé : va donc chercher ta côte de mailles intégrale là (oui c'est en anglais, si tu comptes utiliser des librairies telles que boost::python -- dont la doc officielle est en anglais -- il te faudra aussi maîtriser la langue de shakespeare).
    je suis pas un padawan kamikaze, j'ai déjà utilisé des lib plus complexes que boost::python (wxwidget, QT, api win32, vfw par exemple). j'ai également codé un langage de script transformé au runtime en asm mais il n'était pas finis et pas entièrement débuggué, c'est pourquoi j'ai choisis de prendre python pour le projet que je fais pour l'instant

    Enfin Java c'est cool (pas de pointeurs, aucune allocation statique possible pour les objets, cohérence et parcimonie des librairies -- quelques librairies pour un domaine d'utilisation donné : en c++ t'as générallement 50 librairies par fonction souhaité et peu/pas de framework, c'est à dire de librairie thématique couvrant des domaines : interface graphique / protocole réseaux/ gestion de flux ... --). Python l'est encore plus (typage dynamique ) Donc utilises C++ (la machine de guerre des programmeurs chevronnés) si c'est absoluement nécessaire. Sinon, t'as plus simple comme langage.
    je connais java, c'est par là que j'ai commencé la programmation. mais je trouve que le c++ est le langage le plus simple car on fait ce qu'on veut avec (manipulation de memoire,...), la syntaxe est claire et c'est plus rapide.

    Voilà. Traduction Null Pointer Exception (en plus "poli" c'est pas une exception, c'est détecté à la compilation ici) et ça ne compile pas.
    c'est pas plutôt parce qu'on ne peut pas appeler de fonction membre en dehors d'une fonction?
    de plus, il ne me semble pas que la fonction replace utilise 2 const char*, je crois que c'est 2 iterateurs et un const char*

    mais j'ai maintenant une autre question :
    j'ai une fonction membre de ma classe player qui retourne un objet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    carte* get_carte(){return m_carte;}
    j'ajoute donc dans ma declaration
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    .def("get_carte", &Player::get_carte)
    mais j'obtiens une erreur :
    C:/Boost/boost_1_36_0/boost/python/detail/invoke.hpp: In function `PyObject* boost::python::detail::invoke(boost::python::detail::invoke_tag_< false, true>, const RC&, F&, TC&) [with RC = boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning<carte*>, F = carte*(Player::*)(), TC = boost::python::arg_from_python<Player&>]':
    C:/Boost/boost_1_36_0/boost/python/detail/caller.hpp:223: instantiated from `PyObject* boost::python::detail::caller_arity<1u>::impl<F, Policies, Sig>::operator()(PyObject*, PyObject*) [with F = carte*(Player::*)(), Policies = boost::python::default_call_policies, Sig = boost::mpl::vector2<carte*, Player&>]'
    C:/Boost/boost_1_36_0/boost/python/object/py_function.hpp:38: instantiated from `PyObject* boost::python::objects::caller_py_function_impl<Caller>::operator()(PyObject*, PyObject*) [with Caller = boost::python::detail::caller<carte*(Player::*)(), boost::python::default_call_policies, boost::mpl::vector2<carte*, Player&> >]'
    C:\Program Files\CodeBlocks\projects\source1\ScriptManager.cpp:135: instantiated from here
    C:/Boost/boost_1_36_0/boost/python/detail/invoke.hpp:88: error: no match for call to `(const boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning<carte*>) (carte*)'
    C:/Boost/boost_1_36_0/boost/python/detail/caller.hpp: In static member function `static const PyTypeObject* boost::python::detail::converter_target_type<ResultConverter>::get_pytype() [with ResultConverter = boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning<carte*>]':
    C:/Boost/boost_1_36_0/boost/python/detail/caller.hpp:242: instantiated from `static boost::python::detail::py_func_sig_info boost::python::detail::caller_arity<1u>::impl<F, Policies, Sig>::signature() [with F = carte*(Player::*)(), Policies = boost::python::default_call_policies, Sig = boost::mpl::vector2<carte*, Player&>]'
    C:/Boost/boost_1_36_0/boost/python/object/py_function.hpp:48: instantiated from `boost::python::detail::py_func_sig_info boost::python::objects::caller_py_function_impl<Caller>::signature() const [with Caller = boost::python::detail::caller<carte*(Player::*)(), boost::python::default_call_policies, boost::mpl::vector2<carte*, Player&> >]'
    C:\Program Files\CodeBlocks\projects\source1\ScriptManager.cpp:135: instantiated from here
    C:/Boost/boost_1_36_0/boost/python/detail/caller.hpp:102: error: 'struct boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning<carte*>' has no member named 'get_pytype'
    si je renvois un int à la place de carte*, il n'y a aucun problème.
    j'ai déjà envoyé la définition de carte* juste avant
    la ligne 135 de ScriptManager.cpp est Py_Finalize();

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 11
    Points : 14
    Points
    14
    Par défaut
    Sur le problème des constructeurs implicites zabibof : C'est à moitié vrai, en fait ^^ voilà la version précise

    "But as soon as you declare your own constructor for a class, the compiler no longer provides an implicit default constructor.[etc]" Donc un constructeur implicite qu'on a pas a appelé, fournit un objet, dont toutes les valeurs sont initialisées à nulles : ce qui a peu d'intêret.

    source : http://www.cplusplus.com/doc/tutorial/classes.html

    Je ne prétend pas être un expert en C++ j'ai fais du Java pendant plus de deux ans, et je débute en python, mon expérience en c/c++ est annecdotique : mais je connais les principes de la POO, la notion de template/générique, celle de pointeur, celles autour de l'introspection ... pour autant les messages d'erreurs des compilateurs c++ sont souvent du chinois pour moi et cette librairie boost::python, n'est pas simple à mes yeux bien que j'ai tous les éléments théoriques pour la comprendre (seulement l'habitude du langage ... ça ne s'obtient pas du jour au lendemain ). Enfin je le concède c++ est puissant : "on fait ce que l'on veut avec", je ne dirais pas simple pour autant

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 101
    Points : 75
    Points
    75
    Par défaut
    bon, finalement, j'ai trouvé la solution :
    il faut ajouter return_value_policy<reference_existing_object>()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    .def("get_carte",&Player::get_carte,return_value_policy<reference_existing_object>())

  9. #9
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Citation Envoyé par yves_982 Voir le message
    Sur le problème des constructeurs implicites zabibof : C'est à moitié vrai, en fait ^^ voilà la version précise

    "But as soon as you declare your own constructor for a class, the compiler no longer provides an implicit default constructor.[etc]" Donc un constructeur implicite qu'on a pas a appelé, fournit un objet, dont toutes les valeurs sont initialisées à nulles : ce qui a peu d'intêret.

    source : http://www.cplusplus.com/doc/tutorial/classes.html
    Ce n'est pas à moitié vrai , c'est comme ça c'est tout

    Le fait que le compilateur défini ou non un constructeur par défaut n'influe pas sur la construction de l'objet, quand tu fais: Player player1, cela passe toujours dans le constructeur que ce soit le tien ou celui du compilateur.

    Pour te (re)convaincre, on va laisser le compilateur définir un constructeur par défaut mais pour te montrer qu'un objet a bien été créé, dans le destructeur, on va afficher un message.
    Code 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
     
    #include <iostream>
     
    class MaClasse
    {
    public:
        ~MaClasse()
        {
            std::cout << "On a bien eu un objet\n";
        }
    };
     
    int main()
    {
    	MaClasse belEtBienUnObjet;
    	return 0;
    }
    Resultat: avant que main ne retourne, on a notre message

    Et non, un constructeur par défaut fourni par le compilateur n'a pas peu d'intérêt, au contraire, c'est bien utile quand on n'a pas besoin de valeur précise pour initialiser un attribut ou quand on n'a pas de traitement particulier à faire pendant la construction de l'objet.

    Tu confond avec Java, avec Java, pour créer un objet, on doit toujours passer par new, en C++, on n'utilise new que pour les pointeurs.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 11
    Points : 14
    Points
    14
    Par défaut
    En effet mais j'ai pas vraiement dépassé le helloworld en c++ ce qui explique ma confusion. J'ai appris les même concepts dans d'autres langages, avec le temps, mais du coup la syntaxe et le fonctionnement de c++ c'est pas mon fort

    A la base je pensais juste que delfare était un nouveau programmeur (un jeu mélangeant du c++ et du python ... au premier abord je ne voyais pas l'intêret) donc je me suis permis d'intervenir pour lui conseiller avec humour un autre langage.Pour faire des jeux 2D simples python, Java ... étants je pense plus accessibles que c++ pour débuter. Il s'avère qu'il sait ce qu'il fait, au temp pour moi

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

Discussions similaires

  1. Optimiser l'utilisation des pointeurs
    Par progfou dans le forum C
    Réponses: 65
    Dernier message: 10/03/2006, 11h49
  2. Réponses: 6
    Dernier message: 21/02/2006, 16h47
  3. [BOOST]Comment utiliser la lib boost.python
    Par Invité dans le forum Bibliothèques
    Réponses: 6
    Dernier message: 30/01/2006, 11h35
  4. Utilisation de pointeurs
    Par renard s dans le forum Débuter
    Réponses: 7
    Dernier message: 08/12/2005, 08h18
  5. Utilisation de Pointeurs dans API windows
    Par Drooxy dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 13/03/2003, 22h39

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