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

C Discussion :

Interpreter un void *, librairie newt


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Novembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2016
    Messages : 5
    Points : 2
    Points
    2
    Par défaut Interpreter un void *, librairie newt
    Bonjour,

    Je cherche à utiliser newt pour fournir une interface aux utilisateurs d'un outil que je développe.
    Mon souci: mes notions en C sont assez basiques, et j'avoue avoir du mal à bien utiliser le C dés qu'il s'agit de ce qui sort du commun du calcul scientifique.

    Dans l'exemple ici, j'utilise newt, pour créer une interface avec une liste de choix. La liste est configurée pour fermer le form lorsque l'on presse Enter:

    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
    #include <newt.h>
    #include <stdlib.h>
    #include <stdio.h>
     
    int main(void) {
     
    void * result;
        struct partition * curr;
        newtInit();
        newtCls();
     
        newtComponent form, b1, b2, listbox;
        newtOpenWindow(10, 10, 80, 30, "Button Sample");
        b1 = newtButton(10, 9, "Ok");
        b2 = newtButton(22, 9, "Cancel");
        listbox= newtListbox(10,15,2, NEWT_FLAG_RETURNEXIT);
        newtListboxAppendEntry(listbox, "VALUE1" , "1");
        newtListboxAppendEntry(listbox, "VALUE2" , "2");
        result = newtListboxGetCurrent(listbox);
     
        form = newtForm(NULL, NULL, 0);
        newtFormAddComponents(form, b1, b2, listbox, NULL);
        newtRunForm(form);
     
        newtFormDestroy(form);
     
        newtFinished();
    printf("%p\n",( void * )result);
     
     
    }
    Problème, ce que me retourne newtListboxGetCurrent est un * void (https://sourcecodebrowser.com/newt/0...istbox_8c.html), et je ne vois pas comment utiliser cela. Déjà parce que j’espérais un entier, et ensuite parce que quelque soit mon choix dans la liste, result semble toujours avoir la même valeur: 0x400ca7

    L'un d'entre vous saurais t-il comment bien utiliser cette valeur void ? Ou du moins comment en extraire le choix fait ?

    Pour compiler le programme, il faut installer la newt-devel, puis penser à linker à la compilation:

    gcc -o test.out test.c -lnewt

    Bien cordialement

    Ben

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Si j'en crois ton lien, le void* retourné par newtListboxGetCurrent() est précisément celui que tu as passé en troisième paramètre de newtListboxAppendEntry(), sans aucun changement, aucune copie, etc.
    Ce qui signifie que tu peux le caster en const char * et retrouver tes "1" et "2"... Par exemple, les convertir en entiers avec la fonction strtol().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Fais un effort

    On peut lire sur ta documentation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if (item)
           return (void *)item->data;
        else
           return NULL;
    Il retourne ta donnée personnelle de la liste chainée boxItems (de type struct items *)

  4. #4
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Novembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2016
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Merci pour vos retours.

    Venant du Fortran, mes notions en void et pointeurs sont vraiment light (très peut utilisées en Fortran 95, on ne fait que jouer avec des adresses mémoires, sans aucunes subtilités). D'où ma difficulté ici, mais je me documente

    Donc ici, j'ai rajouté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    const char * toto=result;
    printf("%c\n",toto);
    printf("%p\n",result);
    a la fin du code. Mais le résultat ne varie jamais quelque soit le choix (et j'ai un caractère ascii spécial au lieux d'un numéro):

    Si je comprends bien, la fonction me retourne une adresse mémoire où aller récupérer ma donnée au format char, c'est bien cela ? (puisque je lui ai fournit un char en 3 ieme argument).
    Ou alors c'est une structure, et dans ce cas pour avoir la bonne adresse mémoire je dois utiliser quelque chose du type: (*result).??? ? Mais dans ce cas, je dois bien déclarer le format de ma structure quelque part pour initialiser result, non ?

    Cordialement

    Ben

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je pense que tu fais ton appel à newtListboxGetCurrent() beaucoup trop tôt: Il faut le faire après l'appel à newtRunForm()...

    PS: Attention, printf("%c\n",toto); ne fait pas ce que tu penses: ça affiche l'octet faible du pointeur lui-même en tant que caractère. Pour afficher le caractère pointé, il te faut printf("%c\n", *toto);. Et pour afficher toute la chaîne de caractères, printf("%s\n", toto);.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Novembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2016
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Oui, le problème venait de là. L'appel au get doit logiquement se faire après avoir exécuté le form, et donc après le run. C'est pathétique comme erreur, mais avec la tête dans le guidon ca ma échappé...
    Un grand merci !

    Du coup cela fonctionne. Il faut vraiment que je me plonge dans le C et notamment sur cette histoire de pointeurs. Si j'ai bien compris:
    int toto; est la variable
    &toto renvoie l'adresse de la variable toto en mémoire
    int * tutu;
    tutu = &toto; stocke l'adresse de toto dans tutu

    J'ai beaucoup joué avec ça en Fortran pour économiser la mémoire (on crée au départ des zones de mémoire de travail, puis pour ne pas avoir à allouer/désalouer la mémoire tout le temps et économiser en réutilisant les zones inutilisées, on attribuait des pointeurs à ces zones et un flag "utilisé ou non".), mais la syntaxe est totalement différente.

    Reste à comprendre ce qu'est ce void, c'est un format qui m'est inconnu. Si j'ai bien compris, c'est un format générique, qui peut être lié à un int, un char, etc ?

    Je tag résolu, un grand merci à vous

    Ben

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par benle Voir le message
    Reste à comprendre ce qu'est ce void, c'est un format qui m'est inconnu. Si j'ai bien compris, c'est un format générique, qui peut être lié à un int, un char, etc ?
    void c'est void soit quelque chose soit rien

    Par exemple, lorsqu'une fonction qui ne retourne rien (ou procédure) elle retourne void.

    Un pointeur sur void, c'est un pointeur sur "quelque chose". Cela permet de faire de la généricité.
    Mais, il faut savoir vers quoi on pointe parce qu'il peut y avoir des déférencements, après un cast, qui peuvent plantouiller si on ne sait pas ce qu'on fait

  8. #8
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Novembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2016
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Ca porte bien son nom alors

    Je comprends le besoin de généricité, mais ce qui me fait effectivement un peu peur c'est de ne pas savoir forcément vers quoi on pointe, et la lisibilité d'un code doit s'en ressentir si il y a abus. Et valgrind ne semblais pas plus choqué que ça lors de mes tests quand je tentais d'utiliser le void en int alors qu'il s'agissait d'un char (logique après tout, il ne peut estimer si l'action est justifiée ou non). A débugguer ca promet...
    Je me rends compte que le C autorise beaucoup de manipulations interdites dans d'autres langages.

    Donc je suppose que c'est à utiliser avec modération, et que son usage est restreint à des cas bien particuliers. Si je connais le type, je l'utilise directement.

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par benle Voir le message
    Et valgrind ne semblais pas plus choqué que ça lors de mes tests quand je tentais d'utiliser le void en int alors qu'il s'agissait d'un char
    ce n'est pas vraiment un bon exemple void ne sert pas à masquer un P.O.D. (Pain Old Data): tu prends un int-long 32/ 64 bits et dedans tu peux mettre pleins de types signés ou pas.


    Citation Envoyé par benle Voir le message
    A débugguer ca promet...
    Je me rends compte que le C autorise beaucoup de manipulations interdites dans d'autres langages.
    Et oui, tu n'as pas de machine virtuelle ou autre pour te protéger ... tu es seul avec tes core dumped.

    Il faut apprendre à coder plus ou moins proprement et avoir de bon automatismes


    Citation Envoyé par benle Voir le message
    Donc je suppose que c'est à utiliser avec modération, et que son usage est restreint à des cas bien particuliers.
    Pas du tout C'est pour faire de la généricité. Et c'est le seul moyen (quoique il y a les tagged unions). Et en C++ pour avoir du polymorphisme.
    Regarde ton exemple: tu veux une liste de quelque chose -> void*.

  10. #10
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Novembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2016
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Super à la bourre. Vacances avec déconnexion forcée

    OK je comprends le principe. A l'usage c'est effectivement pratique, surtout pour développer des libs et les partager.
    Par contre, ne pas avoir de sécurités faut vraiment faire attention. Dans le fortran, ya pas vraiment de protection active, plus un langage tellement simple que le compilateur chope toutes les possibilités de problèmes

    Merci encore pour l'aide et les explications

    Ben

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

Discussions similaires

  1. [librairies standard]slang.h et curses.h
    Par miss8 dans le forum Réseau
    Réponses: 13
    Dernier message: 27/12/2002, 10h14
  2. inclure une librairie *.lib
    Par darkbm dans le forum C
    Réponses: 2
    Dernier message: 16/12/2002, 22h48
  3. Réponses: 5
    Dernier message: 09/12/2002, 22h23
  4. [GTK]PB Librairie GTK+ sous dev-c++
    Par wozzy dans le forum Dev-C++
    Réponses: 15
    Dernier message: 05/11/2002, 14h55
  5. compatibilité des librairies directX8
    Par Freakazoid dans le forum DirectX
    Réponses: 3
    Dernier message: 23/05/2002, 21h33

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