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 :

faire une set


Sujet :

Interfaçage autre langage Python

  1. #1
    Membre régulier
    Inscrit en
    Février 2009
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 141
    Points : 91
    Points
    91
    Par défaut faire une set
    Bonjour a tous!

    J'expose mon problème.

    J'ai un soft.
    Ce soft me fourni des datas que je peux appeller grâce a python
    Depuis python,j'utilise les fonctions pour avoir les datas que je veux.
    Je me fais des structures de data de types dico ou autre en python.

    Depuis C++, j'utilise la librairie Cpython pour faire mes get et prendre ce que je veux depuis Python(voir mes posts précédents notamment ceux avec Tamiel qui en connait un rayon en interfacage).
    En C++, je me fais donc mes map ou vector. Tout ceci fonctionne a merveille.

    Mon pb commence ici, je veux maintenant faire un set.
    Je m'explique, j'ai en C++, mes datas.
    Imaginons que je veuille changer ma data TUTU en TOTO.
    Pas de probleme, j'utilise la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PyList_SetItem(retval,180,PyString_FromString("TUTUETTOTO"));
    Ceci fonctionne parfaitement aussi.

    Maintenant, je veux que ce changement se fasse dans mon soft de depart.
    J'utilise alors dans python la fonction qui permet d'écrire dans ce soft : je change même de nom pour le soft (palmier.extension en palmerais.extension).
    J'appelle cette fonction depuis C++ et ca fonctionne aussi.

    Vous allez me dire que tt fonctionne....
    Mais non, lorsque j'ouvre palmerais.extension, je ne vois pas la modification de TUTU en TOTO.

    Pourtant dans la memoire TUTU vaut bien TOTO....
    QQ chose m'échappe.

    Tamiel si tu as une idée, je te remercie d'avance.
    Merci pour toutes les futurs reponses.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 271
    Points : 329
    Points
    329
    Par défaut
    Salut julien25,

    je n'ai pas compris la fin de ton explication :
    Maintenant, je veux que ce changement se fasse dans mon soft de depart.
    J'utilise alors dans python la fonction qui permet d'écrire dans ce soft : je change même de nom pour le soft (palmier.extension en palmerais.extension).
    J'appelle cette fonction depuis C++ et ca fonctionne aussi.

    Vous allez me dire que tt fonctionne....
    Mais non, lorsque j'ouvre palmerais.extension, je ne vois pas la modification de TUTU en TOTO.

    Pourtant dans la memoire TUTU vaut bien TOTO....
    Tu as un code C++ qui appelle une fonction en python qui va écrire dans le fichier palmerais.extension ?

    Si oui, peux tu nous montrer le code C++ et le code Python qui correspondent à cette étape de ton programme ?

  3. #3
    Membre régulier
    Inscrit en
    Février 2009
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 141
    Points : 91
    Points
    91
    Par défaut
    Salut Tamiel,


    Tu as un code C++ qui appelle une fonction en python qui va écrire dans le fichier palmerais.extension ?
    Oui c'est exactement cela.

    Je peux te montrer une partie qui t'aidera mieux a comprendre.
    Cette partie, elle est écrite dans mon C++.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    func_set = PyDict_GetItemString(PyModule_GetDict(mymod), "set_Ipsa");
    class_set = PyEval_CallObject(func_set,NULL);
    retval = PyObject_CallMethod(class_set, "Setmethods",NULL);
    Elle va lire ce qui se trouve dans mon python :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class set_Ipsa():
        def Setmethods(self):
            net.WriteFile("palemerais.iif")
    le WriteFile est une fonction qui existe dans la librairie du software de depart.
    Lorsque j'execute la fonction dans mon C++, mon fichier palemerais(peu importe le nom)se cre bien.

    Mais mon set fonctionne ne fait aucun changement.
    Ce set est fait via un : (dans le C++)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PyList_SetItem(retval_loads,indeofsettingloads,PyString_FromString("TUTUETTOTO"));
    Je me demande si ceci est bien change dans l'espace mémoire de python?
    Normalement oui.
    Déjà quelque jour de réflexion sur ce pb...

    Une chose est sure, si j'arrive a faire mes get, les set devrait marcher ...

    Tamiel, as tu compris ce que je faisais?



    En tout Merci beaucoup Tamiel.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 271
    Points : 329
    Points
    329
    Par défaut
    Quand tu déclares ta classe set_Ipsa, si celle-ci ne dérive d'aucune classe, les parenthèses sont à proscrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class set_Ipsa:
        def Setmethods(self):
            print "palemerais.iif"
    Je remplacerais juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    class_set = PyEval_CallObject(func_set,NULL);
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    class_set = PyInstance_New(func_set,NULL, NULL);
    PyEval_CallObject n'est plus d'actualité dans python version >= 2.6 .




    Logiquement en remplaçant ta classe par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class set_Ipsa:
        def Setmethods(self):
            print "palemerais.iif"
    ça doit afficher "palemerais.iif"
    donc le code est exécuté correctement et on peut en déduire que le problème se situe au niveau de l'appel de :
    net.WriteFile(filename)


    Après je suppose que ton set (PyList) est passé à un moment donné à l'instance de ta classe set_Ipsa ou à l'instance net ?

  5. #5
    Membre régulier
    Inscrit en
    Février 2009
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 141
    Points : 91
    Points
    91
    Par défaut
    Merci une nouvelle fois de tes nombreuses pistes.
    J'ai fais le print, il fonctionne sans aucun pb.
    Le fichier est bien crée d'autant plus que je peux l'ouvrir.

    Je pense que le soft de départ me fournit une certaine structure, une certaine data base.
    Quand j'effectue mon set, PyList_Set, je fais mon set sur des listes est non un dico. Je perds alors la structure de donnée de départ.
    Cela dit je suis sur que mon set fonctionne car je l'affiche au niveau de C++ et je vois la différence.

    A mon avis, mais je ne sais pas encore comment faire, il faut que je fasse des methodes set dans le python lui même, que je puisse appelé depuis C++.
    Pour le moment mon set ne se fait que depuis C++.
    Qu'en penses tu?


    Après je suppose que ton set (PyList) est passé à un moment donné à l'instance de ta classe set_Ipsa ou à l'instance net ?
    Mon set je le fais au niveau de mon constructeur dans mon C++ via la fonction PyList_Set.
    Ca doit être le problème.

    Merci encore

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 271
    Points : 329
    Points
    329
    Par défaut
    Un exemple simple pour une méthode de type "set" :

    le code C appelant le module python :
    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
     
    #include <Python.h>
    #include "structmember.h"
     
    int main(int argc, char *argv[])
    {
     
      PyObject *mod, *mdict, *pyclass, *pyinstance, *result, *mylist;
      int i;
      /* init py env */
      Py_Initialize();
     
      PyRun_SimpleString("import sys; sys.path.insert(0, '.')");
      /* import module */
      mod = PyImport_ImportModule("testmodule");
     
      /* get module __dict__ */
      mdict = PyModule_GetDict(mod);
     
      /* form __dict__ get class  */
      pyclass = PyDict_GetItemString(mdict, "Toto");
     
      /* make class instance */
      pyinstance = PyInstance_New(pyclass, NULL, NULL);
     
      /* create and populate list */
      mylist = PyList_New(0);
      for(i=0; i<10; i++)
      {
        PyList_Append(mylist, PyInt_FromLong((long)i));
      }
     
      /* use method setList() with argument mylist */
      PyObject_CallMethod(pyinstance, "setList", "O", mylist);
     
      /* print list */
      result = PyObject_CallMethod(pyinstance, "printList", NULL);
      Py_XDECREF(result);
     
      /* finally release references */
      Py_XDECREF(pyinstance);
      Py_XDECREF(pyclass);
      Py_XDECREF(mdict);
      Py_XDECREF(mod);
      Py_Finalize();
      return 0;
    }
    Dans la fonction PyObject_CallMethod(), on utilise les arguments disponibles dans l'api C Python :
    http://docs.python.org/c-api/arg.html?highlight=pyarg

    Ici on veut un argument de type PyList qui est un PyObject *, donc "O" .

    et

    le module python :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Toto:
      def __init__(self):
        self.mylist = None
     
      def setList(self, mylist):
        self.mylist = mylist
     
      def printList(self):
        print "MyList is :",self.mylist

    Dans ton programme, il faut que tu "passes" à ton instance de classe set_Ipsa ta liste car cette instance n'a pas de visibilité sur ta liste à moins que tu n'ajoutes explicitement ta liste à globals() mais c'est moche.

  7. #7
    Membre régulier
    Inscrit en
    Février 2009
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 141
    Points : 91
    Points
    91
    Par défaut
    Bonjour Tamiel,
    effectivement je n'envoyais pas mon changement (set) à mon Python
    Le set se faisait uniquement dans la mémoire alloué par C++.

    J'ai fais exactement comme tu as fait et ça fonctionne très bien.
    Il plante juste si je laisse le Py_Finalize().
    J'ai bien fait attention a décrémente les références même si je ne sais pas trop encore à quoi ça sert.

    Je te remercie vraiment chaleureusement de ton aide très très précieuse.
    Je te souhaite également une excellente fin de semaine.

    Julien

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 271
    Points : 329
    Points
    329
    Par défaut
    Py_Finalize() doit être appelé à la fin pour détruire l'interpréteur Python initialisé avec Py_Initialize() car ceci permet de libérer la mémoire allouée/utilisée par l'interpréteur Python.

    Py_Initialize doit être au début du code avant toute manipulation de *PyObject .

    A mon avis tout ce qui est alloué à partir de Py_Initialize() doit être libéré avant Py_Finalize() .

    Je ne sais pas si tu utilises des malloc/calloc/realloc/free dans cette partie du code mais il faut peut être s'orienter vers cette piste.

    A voir aussi : tu passes ton set de type PyList à une méthode, donc tu dois augmenter le compteur de référence de cet objet de 1 avec Py_INCREF. (Tu vas rajouter une référence de ton set dans l'instance de classe donc il faut bien dire à la vm de python que tu as ajouté une référence manuellement.)

    Sinon tu peux débuguer avec gdb (si tu utilises gcc pour compiler avec le flag -g ) et faire un backtrace pour cibler l'erreur.

    Bonne fin d'après midi !

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

Discussions similaires

  1. faire un set(handle) avec une fonction externe
    Par sellamelie dans le forum Interfaces Graphiques
    Réponses: 5
    Dernier message: 12/07/2011, 14h11
  2. [XSLT] Faire une boucle sur une variable [i]
    Par PoT_de_NuTeLLa dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 07/06/2010, 12h45
  3. Faire une Boucle pour lire dans Settings.settinge
    Par totoen dans le forum Windows Forms
    Réponses: 0
    Dernier message: 27/10/2008, 10h44
  4. Faire une liste de device??
    Par jackjack dans le forum DirectX
    Réponses: 1
    Dernier message: 23/05/2003, 14h43
  5. [XSL]faire une balise dans une balise??? (ComboBox)
    Par rastoix dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 23/05/2003, 08h34

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