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 :

python C API: convertir une struct C en Class python


Sujet :

Interfaçage autre langage Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut python C API: convertir une struct C en Class python
    Salut a tous,

    Nous voulons convertir une struct

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    typedef struct {
            PyObject_HEAD
            int first, second;
        } intpair;
    en une class (en suivant l'example 25.2 donne dans "Python in a Nutshell, 2nd Edition" )

    On obtient bien une class mais __dict__ montre une doc string vide et ne contient pas les membres "first" et "second"...
    De plus, la fonction d'initialisation intpair_init (voir plus bas) n'as pas l'air d'etre executee du tout car le commande printf de debuggage ne s'affiche pas

    1) Soit, on fait l'initialisation de maniere erronee.
    2) soit on a un problem avec l'ordre des champs dans PyTypeObject
    3) ou ???

    merci d'avance pous vos suggestions
    David, Juergen


    On utilise la definition de PyTypeObject a partir de usr/lib/python2.5/doc/commontex/typestruct.h (voir plus bas):
    et les fonctions intpair_dealloc,intpair_str, intpair_init.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    static int intpair_init(PyObject *self , PyObject *args, PyObject *kwds)
    {
      static char* nams[] = {"first","second",NULL};
      int first, second;
      printf("1 in init\n");fflush(stdout);
      if(!PyArg_ParseTupleAndKeywords(args, kwds, "ii", nams, &first, &second))
          return -1;
      ((intpair*)self)->first = 101;
      ((intpair*)self)->second = 102;
      printf("in init\n");
      return 0;
    }
    avec intpair_members:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    static PyMemberDef intpair_members[] = {
      {"first", T_INT, offsetof(intpair, first), 0, "first item" },
      {"second", T_INT, offsetof(intpair, second), 0, "second item" },
      {NULL}
    };
    l'initialisation est faite avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void initintpair(void)
    {
      static PyMethodDef no_methods[] = { {NULL} };
      PyObject* this_module = Py_InitModule("intpair", no_methods);
      PyType_Ready(&t_intpair);
      PyObject_SetAttrString(this_module, "intpair", (PyObject*)&t_intpair);
    }


    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
     
    static PyTypeObject t_intpair = {
     PyObject_HEAD_INIT(NULL)
      0,
      "intpair.intpair", /* For printing, in format "<module>.<name>" */
      sizeof(intpair),
      0, /* For allocation */
      /* Methods to implement standard operations */
      intpair_dealloc,
      0,
      0,
      0,
      0,
      intpair_str,
     /* Method suites for standard classes */
      0,
      0,
      0,
      /* More standard operations (here for binary compatibility) */
      0,
      0,
      0,
      PyObject_GenericGetAttr,
      PyObject_GenericSetAttr,
      /* Functions to access object as input/output buffer */
      0,
      /* Flags to define presence of optional/expanded features */
      Py_TPFLAGS_DEFAULT,
      "two ints (first,second)", /* Documentation string */
      /* Assigned meaning in release 2.0 */
      /* call function for all accessible objects */
      0,
      /* delete references to contained objects */
      0,
      /* Assigned meaning in release 2.1 */
      /* rich comparisons */
      0,
      /* weak reference enabler */
      0,
      /* Added in release 2.2 */
      /* Iterators */
      0,
      0,
      /* Attribute descriptor and subclassing stuff */
      0,
      intpair_members,
      0,
      0,
      0,
      0,
      0,
      0,
      intpair_init,
      PyType_GenericAlloc,
      PyType_GenericNew ,
      _PyObject_Del, /* Low-level free-memory routine */
      0,
      0,
      0,
      0,
      0,
      0
    };

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Pour répondre à la 1ère question:

    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
     
    class intpair(object):
        def __init__(self, first=0, second=0):
            self.first = first
            self.second = second
     
    # instanciation en laissant les valeurs par défaut first=0, second=0
    x = intpair()
     
    # modif des valeurs
    x.first = 42
    x.second = 75
     
    # instanciation avec initialisation first=5, second=10
    y = intpair(5,10)
     
    # accès aux valeurs de x:
    print x.first  # affiche 42
    print x.second  # affiche 75
    print y.first  # affiche 5
    print y.second  # affiche 10
    Les variables internes à la classe et préfixées par self appartiennent à l'instance de classe et sont accessibles avec le préfixe self dans toutes les méthodes de la classe.

    Tyrtamos

  3. #3
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut
    merci pour ta reponse mais je voudrais initialiser les valeurs de "first" et "second"
    de la class a partir du code C et non pas dans python.

    en C, j'ai ajoute la ligne suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ((intpair*)self)->first = 101;
    dans la fonction intpair_init mais celle-ci ne semble pas etre appele.....

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Désolé, je n'ai aucune expérience sur le sujet.

    Voir la doc? => http://docs.python.org/ext/ext.html

    Tyrtamos

  5. #5
    Membre confirmé
    Inscrit en
    Février 2007
    Messages
    106
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2007
    Messages : 106
    Par défaut
    merci je connais cet doc...mais elle est franchement pas terrible....

  6. #6
    Membre chevronné
    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
    Par défaut
    Pour que init_intpair soit invoquée, il faut la déclarer comme ci-dessous dans la déclaration de la structure PyTypeObject :
    (initproc)init_intpair

    Un détail : appelle l'initialisation du module intpair comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
    #define PyMODINIT_FUNC void
    #endif
    PyMODINIT_FUNC initintpair(void)
    {
      static PyMethodDef no_methods[] = { {NULL} };
      PyObject* this_module = Py_InitModule("intpair", no_methods);
      PyType_Ready(&t_intpair);
      PyObject_SetAttrString(this_module, "intpair", (PyObject*)&t_intpair);
    }


    Sinon ton code est l'exemple de l'api C/Python .

    Si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    python
    >>> import initpair
    >>> dir(intpair.intpair)
    et aussi
    tu devrais voir les membres déclarés de ta classe dans les deux cas.


    Remarque :
    Dans ton exemple de code, finalement ce n'est pas un "binding" de structure C mais la création d'un module en C contenant une classe .

Discussions similaires

  1. Convertir une énumération Java en class C++
    Par yo0shii-78 dans le forum C++
    Réponses: 1
    Dernier message: 03/04/2015, 23h04
  2. Réponses: 0
    Dernier message: 18/03/2015, 10h23
  3. Réponses: 3
    Dernier message: 15/04/2014, 09h17
  4. [Python API] Appeller une fonction Python depuis le C++
    Par wetneb dans le forum Bibliothèques
    Réponses: 0
    Dernier message: 18/10/2007, 12h49

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