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 :

Retourner un array avec ctypes


Sujet :

Interfaçage autre langage Python

  1. #1
    Membre averti
    Inscrit en
    Janvier 2007
    Messages
    329
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 329
    Points : 366
    Points
    366
    Par défaut Retourner un array avec ctypes
    Salut à tous !

    J'essaie de faire une bibliothèque en C et d'y accéder depuis Python. J'ai choisi d'utiliser ctypes.

    Le problème, c'est que je souhaite retourner un Array, mais je n'y arrive pas. Voici mon code :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    /* Fichier: bidule.c */
     
    #include <stdio.h>
     
    /*---------------------------------------------------------------------------*/
     
    long *toto(int n) {
     
        int i;
        long img[n*n];
     
        for (i=0; i<n*n; i++) {
            img[i] = i;
        };
     
        return img; /*&img[0][0];*/
    }
     
    /*---------------------------------------------------------------------------*/
     
    int tata(int n) {
     
        int i;
        long *t = toto(n);
     
        for (i=0; i<n*n; i++) {
            printf("%ld ", t[i]);
        };
        printf("\n-----\n");
     
        return n;
    }
     
    /*---------------------------------------------------------------------------*/
    que je compile avec :
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    gcc -shared -Wl,-soname,bidule.so.1 -o bidule.so bidule.o
    gcc -Wall -fPIC -c bidule.c


    Mon code python est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    from ctypes import cdll, c_int, c_long, c_double
     
    mylib = cdll.LoadLibrary("bidule.so")
    dim = 3
     
    mylib.tata.argtypes = [c_int]
    x = mylib.tata(dim)
     
    mylib.toto.argtypes = [c_int]
    mylib.toto.restype = c_long * (dim**2)
    x = mylib.toto(dim)
    print type(x)
    print [_ for _ in x]
    Le résultat est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    0 1 2 3 4 5 6 7 8 
    -----
    <class '__main__.c_long_Array_9'>
    [-1075527424, 148238472, 0, -1208711504, 8191, 0, 148518376, -1208037388, -1207760664]
    La 1ère ligne est renvoyée par la fonction "tata" et la dernière par python. Normalement, ça aurait du être [0,1,2,3,4,5,6,7,8]


    Il se peut que le problème vienne du code C, car malgré le fait que "tata" retourne bien "0 1 2 3 4 5 6 7 8", j'ai cette erreur à la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    gcc -Wall -fPIC -c bidule.c
    bidule.c: In function ‘toto’:
    bidule.c:16: attention : cette fonction retourne l'adresse d'une variable locale
    gcc -shared -Wl,-soname,bidule.so.1 -o bidule.so bidule.o

    Merci d'avance à tous ceux qui essaieront de comprendre


    PS : je suis sous Linux, gcc-4.3.2, python-2.5.4

    -

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Ton problème est dans le code C, pas dans le code Python.

    La variable img est un pointeur sur des données déclarées localement, qui ne persistent donc pas après que la fonction ait retourné. Alloue ton tableau avec calloc plutôt.

  3. #3
    Membre averti
    Inscrit en
    Janvier 2007
    Messages
    329
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 329
    Points : 366
    Points
    366
    Par défaut
    Merci pour ta réponse.

    Effectivement, vu après coup, ça paraît logique (faut vraiment que je prenne des vacances, moi...)

    J'ai donc contourné le problème en déclarant l'array dans mon code python, et en le passant par référence à la fonction C. En même temps, ça me permet d'utiliser un array à 2 dimensions, ce que je n'étais pas non plus arrivé à faire.

    Mon code C :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void toto(int n, long img[n][n]) {
        int i, j;
     
        /* valeur = produit des indices */
        for (i=0; i<n; i++) {
            for (j=0; j<n; j++) {
                img[i][j] = i * j;
            };
        };
    }


    Mon code python :
    Code python : 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
     
    from ctypes import cdll, c_int, c_long, c_double
     
    def array2list(array):
        return [[b for b in a] for a in array]
     
     
    # Initialisation
    mylib = cdll.LoadLibrary("bidule.so")
    dim = 3
    Array = (c_long * dim) * dim
     
    # Tableau 2D
    array = Array()
    for i in xrange(dim):
        for j  in xrange(dim):
            array[i][j] = c_long(i + j)
    print array2list(array)   # Valeur = somme des indices
     
    # Appel "toto"
    mylib.toto.argtypes = [c_int, Array]
    mylib.toto(dim, array)
    print array2list(array)   # Valeur = produit des indices

    Et ça marche parfaitement !


    Encore merci

    -

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

Discussions similaires

  1. [VB.NET] Problème avec CType
    Par ricil78 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 27/02/2007, 17h00
  2. [C# 1.1] Comment retourner une ArrayList avec un WS ?
    Par pi05 dans le forum Services Web
    Réponses: 6
    Dernier message: 09/02/2007, 13h00
  3. [Tableaux] retourner un array ou un champs
    Par ozzmax dans le forum Langage
    Réponses: 7
    Dernier message: 29/09/2006, 17h16
  4. Réponses: 16
    Dernier message: 24/11/2005, 12h43
  5. Retourner une valeur avec une fonction
    Par stephtbest dans le forum ASP
    Réponses: 4
    Dernier message: 31/10/2003, 16h37

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