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

MATLAB Discussion :

passer et récupérer des tableaux d'entiers [MEX]


Sujet :

MATLAB

  1. #1
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut passer et récupérer des tableaux d'entiers
    Bonjour,

    Je commence tout juste à interfacer MATLAB avec du codes C.
    Pour l'instant, j'essaye de comprendre un peu l'API.

    Je sais passer et récupérer des double. Voici le code de test qui me fait ça :
    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
    #include <mex.h>
     
    void mexFunction(int n_outputs, mxArray *p_outputs[], int n_inputs, const mxArray *p_inputs[]) {
     
        double a = mxGetScalar(p_inputs[0]);
        mexPrintf("a = %g\n", a) ;
     
    //associate outputs 
        const mwSize di[2] = {1, 8} ;
        mxArray *c_out_m = p_outputs[0] = mxCreateNumericArray(2, di, mxDOUBLE_CLASS, mxREAL);
     
    //associate pointers
        double *c = mxGetPr(c_out_m);
     
    // do something
        for (int u=0; u!=8; u++) {
            c[u] = a ;
        }
     
        return;
    }

    Le joli résultat est celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >> mex entrees_sorties.cpp
     
    Warning: You are using gcc version "4.6.3-1ubuntu5)".  The version
             currently supported with MEX is "4.3.4".
             For a list of currently supported compilers see: 
             http://www.mathworks.com/support/compilers/current_release/
     
    >> A = entrees_sorties(12.5)
    a = 12.5
     
    A =
     
       12.5000   12.5000   12.5000   12.5000   12.5000   12.5000   12.5000   12.5000
    Ce que je n'arrive pas à faire : exactement la même chose mais sur des entiers (passer un tableau d'entiers en arguments, travailler en C sur ces entiers, retourner le résultat en entier, sans jamais dupliquer inutilement les données en double.

    Merci de votre aide
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Qu'as-tu essayé pour les entiers ?
    Qu'entends-tu par
    Citation Envoyé par ol9245 Voir le message
    sans jamais dupliquer inutilement les données en double.
    ?

  3. #3
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut
    Merci pour ton passage.

    Pour les entiers, je n'ai rien trouvé.
    Je suis bloqué par l'instruction suivante (ligne 13 de mon premer post):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    double *c = mxGetPr(c_out_m);
    La fonction renvoie obligatoirement un double*. Je n'ai aps trouvé dans la doc d'équivalent qui renvoie un int* ou un "ce que je veux"*

    J'ai donc fait ce petit script dans l'espoir que quelqu'un puisse me le convertir pour des entiers.

    Je répète que j'en suis à mes tout-débuts dans la prise en main de cette API. Donc je ne crois pas que la solution soit ni loin ni compliquée. Simplement je ne l'ai pas vue dans la doc ni dans mes recherches.
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

  4. #4
    Invité
    Invité(e)
    Par défaut
    doc mxGetData retournant un void * que tu peux caster par la suite.

  5. #5
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut
    ça n'a pas marché
    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
    #include <mex.h>
     
    void mexFunction(int n_outputs, mxArray *p_outputs[], int n_inputs, const mxArray *p_inputs[]) {
     
        int a = mxGetScalar(p_inputs[0]);
        mexPrintf("a = %g\n", a) ;
     
    //associate outputs 
        const mwSize di[2] = {1, 8} ;
        mxArray *c_out_m = p_outputs[0] = mxCreateNumericArray(2, di, mxDOUBLE_CLASS, mxREAL);
     
    //associate pointers
        int *c = (int*) mxGetPr(c_out_m);
     
    // do something
        for (int u=0; u!=8; u++) {
            c[u] = a ;
        }
     
        return;
    }

    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >> a = int16(12) ; A = entrees_sorties(a)
    a = 6.89886e-310
     
    A =
     
      1.0e-312 *
     
        0.2546    0.2546    0.2546    0.2546         0         0         0         0
     
    >>
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

  6. #6
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 165
    Points
    53 165
    Par défaut
    Mais si :

    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
    #include "mex.h"
     
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]
            )
     
    {
     
        unsigned char *pr, *pl;
        mwSize i, dims[2] = {0,0};
     
        if(!mxIsUint8)
            mexErrMsgTxt("Array must of class uint8");
     
        pr = (unsigned char *)mxGetData(prhs[0]);
     
        dims[0] = mxGetM(prhs[0]);
        dims[1] = mxGetN(prhs[0]);
     
        plhs[0] = mxCreateNumericArray(2, dims, mxUINT8_CLASS, mxREAL);
     
        pl = (unsigned char *)mxGetData(plhs[0]);
     
        for(i=0;i<dims[1]*dims[0];i++)
            pl[i] = pr[i]*2;
     
        mxSetData(plhs[0],pl);
     
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >> A = randi(127,1,10,'uint8')
     
    A =
     
      104  116   17  116   81   13   36   70  122  123
     
    >> B = test(A)
     
    B =
     
      208  232   34  232  162   26   72  140  244  246
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  7. #7
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut
    merci++ Dut
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par ol9245 Voir le message
    ça n'a pas marché
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    double mxGetScalar(const mxArray *pm);
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    double *mxGetPr(const mxArray *pm);
    À part ça il est où mon mxGetData ?
    Ensuite int16 est plutôt représenté par un short (enfin après cela peut dépendre du compilateur...).

    @Dut : il me semble que mxSetData(plhs[0],pl); est inutile vu que l'on fait pl = (unsigned char *)mxGetData(plhs[0]); non ?
    [EDIT] if(!mxIsUint8), il manque l'entrée prhs[0]

  9. #9
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 165
    Points
    53 165
    Par défaut
    Citation Envoyé par ol9245 Voir le message
    merci++ Dut
    Winjerome a donné la solution, j'ai juste mis l’exemple

    Pour plus d'informations sur les différentes classes dans les fichiers MEX, je conseille d'analyser le code C contenu dans le fichier explore.c dans le sous-dossier extern/examples/mex du dossier d'installation de MATLAB.

    Citation Envoyé par Winjerome Voir le message
    @Dut : il me semble que mxSetData(plhs[0],pl); est inutile vu que l'on fait pl = (unsigned char *)mxGetData(plhs[0]); non ?
    Oui... je l'avais laissé passque je m'étais embrouillé entre pr et pl en écrivant le code vite fait
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  10. #10
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 165
    Points
    53 165
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    Ensuite int16 est plutôt représenté par un short (enfin après cela peut dépendre du compilateur...).
    => FAQ C : Les types et les variables
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  11. #11
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    double mxGetScalar(const mxArray *pm);
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    double *mxGetPr(const mxArray *pm);
    À part ça il est où mon mxGetData ?
    Ensuite int16 est plutôt représenté par un short (enfin après cela peut dépendre du compilateur...).

    @Dut : il me semble que mxSetData(plhs[0],pl); est inutile vu que l'on fait pl = (unsigned char *)mxGetData(plhs[0]); non ?
    [EDIT] if(!mxIsUint8), il manque l'entrée prhs[0]
    Je comprends pas tout ce que tu dis

    Là je débute à partir de zéro avec cette API donc le mieux pour moi est d'avoir un exemple simple, qui marche, que je comprend, et que je peux réutiliser pour mes besoins du moment. Après, je pourrai capitaliser peu à peu sur ces acquis. Pour l'instant, je ne sais pas la différence entre mxGetData, mxGetScalar etc. et ma manière d'apprendre ne consiste pas à se palucher des dizaines de pages de doc avant de cracher la première ligne de code : je cherche à récupérer des petits bouts de code qui marchent et à progresser step-by-step à partir de ça en fonction des besoins.
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

  12. #12
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par ol9245 Voir le message
    Je comprends pas tout ce que tu dis
    Ce serait constructif de me dire quelles parties.

    Se plonger dans la documentation est pourtant le meilleur moyen d'y arriver.
    Et si tu veux des exemples, outre celui déjà fourni par Dut tu as justement ceux de la documentation. Rien que celle de mxGetData en contient 6 (dont explore.c mentionnée par Dut).

  13. #13
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    Ce serait constructif de me dire quelles parties.

    Se plonger dans la documentation est pourtant le meilleur moyen d'y arriver.
    Et si tu veux des exemples, outre celui déjà fourni par Dut tu as justement ceux de la documentation. Rien que celle de mxGetData en contient 6 (dont explore.c mentionnée par Dut).
    Bien sur, je lis les docs ! mais pas en linéaire en commençant par la page 1. Je ne crois pas avoir rien inventé. Tous ceux qui apprennent en travaillant doivent faire +/- la même chose. on a des échéances et des impératifs et au milieu de ça on cherche à en apprendre le plus possible sans trop impacter la productivité.
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Lire la documentation en diagonale, qui ne l'a pas fait.

    Pour te dire à quel point cela peut être rapide : tu va dans la documentation générale des MEX-Files (Google "MATLAB MEX-Files" saura t'y conduire rapidement ) puis dans la partie C/C++ Examples tu peux facilement voir Handle 8-, 16-, and 32-Bit Data où tu peux voir les deux premiers paragraphes :
    You can create and manipulate signed and unsigned 8-, 16-, and 32-bit data from within your MEX-files. The MATLAB API provides a set of functions that support these data types. The API function mxCreateNumericArray constructs an unpopulated N-dimensional numeric array with a specified data size. Refer to the entry for mxClassID in the online reference pages for a discussion of how the MATLAB API represents these data types.

    Once you have created an unpopulated MATLAB array of a specified data type, you can access the data using mxGetData and mxGetImagData. These two functions return pointers to the real and imaginary data. You can perform arithmetic on data of 8-, 16-, or 32-bit precision in MEX-files and return the result to MATLAB, which recognizes the correct data class.
    avec un petit fichier exemple à consulter.

    Voilà en même pas 1 minute, tu as tout sous la main

  15. #15
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 53 165
    Points
    53 165
    Par défaut
    Ce qu'il faut bien comprendre, c'est que MATLAB ne connaît que les mxArray.

    Donc en entrée et en sortie d'un fichier MEX, il n'y a que des (pointeurs sur) mxArray

    Ensuite, pour y accéder à partir du langage C, on utilise des fonctions toutes faites (comme mxGetPr ou MxGetM par exemple) qui vont "piocher" directement dans la structure du mxArray les informations utiles.
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  16. #16
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut
    merci infiniment à vous deux pour l'aide.
    c'est vraiment ce dont j'avais besoin.

    et merci à winjerome pour les liens sur les pages exactes dont j'avais besoin (et que je n'avais pas trouvées tout seul, shame on me)

    je mets "résolu". Je reviendrai poster éventuellement le code final pour documenter le fil en vue de futurs internautes qui tomberaient dessus.
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

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

Discussions similaires

  1. Tkinter.Button : passer et récupérer des valeurs
    Par Loïc B. dans le forum Tkinter
    Réponses: 4
    Dernier message: 20/11/2008, 20h48
  2. Comment passer et récupérer des parametres ?
    Par olibara dans le forum C#
    Réponses: 15
    Dernier message: 01/04/2008, 15h07
  3. [Tableaux] Récupérer des cases à cocher
    Par amestoche dans le forum Langage
    Réponses: 1
    Dernier message: 27/04/2007, 21h29
  4. Récupérer données des tableaux issus des formulaires
    Par Romalafrite dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 19/02/2007, 15h18
  5. [Tableaux] Récupérer des Infos CLIENT
    Par maroweb dans le forum Langage
    Réponses: 11
    Dernier message: 02/02/2006, 22h40

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