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 :

une class dans un void*


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 3
    Par défaut une class dans un void*
    bonjour a tous !

    je suis actuellement en train de programmer un petit system qui me permet d'appeller une fonction grace a une chaine ...

    petit exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    add_cmd("print",&print); // ajout la commande et de sa fonction
    cmd("print"); // vas cherche si une commande s'appele printf puis appele sa fonction
    pour sa j'utilise donc 2 type de variable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void (*pt)(); // pour stoker le pointeur de la fonction
    char* cmd; // pour stoker la chaine
    le tout dans une class :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class BW_cmd_struc
    {
        public :
            void (*pt)();
            char* cmd;
    };
    afin de simplifier la gestion j'utilise une liste doublement chainée de structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct dll
    {
       struct dll *prev;
       struct dll *next;
       void *data;
    };
    jusque ici pas de probleme , je tape ma fonction add_cmd(); (elle est pas encore finaliser)
    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
    bool BWconsol::add_cmd(char* commande,void (*pFunction) ())
    {
        if(commande == NULL)
        return false;
     
        //if(pFunction > 0)
        //return false;
     
     
        BW_cmd_struc *Packcmd = NULL;
        Packcmd = new BW_cmd_struc;
     
        if(Packcmd == NULL)
            printf("pas ok\n");
     
        Packcmd->cmd= commande;
        Packcmd->pt = pFunction;
     
        dll_insert(&commande_stok, &Packcmd);
     
        return true;
    }
    -> commande_stok est la liste doublement chainée declarer dans la class principal
    -> dll_insert(); me permet d'inserer une nouveaux noeud dans ma chaine et donc ici ma classe Packcmd

    et quand je l'appelle tout marche bien (aucun plantage)

    alors je passe a ma fonction cmd();
    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
    void BWconsol::cmd(char* commande)
    {
        if(commande==NULL)
            return ;
    
        BW_cmd_struc *Packcmd = NULL;
        Packcmd = new BW_cmd_struc;
        
        int size = dll_sizeof(commande_stok); // permet de conaitre la taille de la chaine
    
        dll_first (&commande_stok); // me pemet de me placer au debut de la chaine
        while (size > 0)
        {
            printf("ok\n");
            Packcmd = (BW_cmd_struc*) dll_data(commande_stok); // je recupere la classe dans le void
            
            if(Packcmd == NULL)
                printf("pas ok\n");
            
            char *temp1 = Packcmd->cmd; // bug ici
            
    
            printf("ok\n");
            if(strcmp(temp1,commande)==0)
            {
                //(*Packcmd.pt) (); // enlever pour les tests
                return ;
            }
            
            dll_next (&commande_stok); // passe a l'element suivant
        }
        return ;
    }
    - les printf("ok\n"); me permet de voir ou est l'erreur

    je lance donc mon programme (en mode console et mode debug sur dev-c++) :
    - je voie le 1er "ok" dans la fonction cmd
    - puis "pas ok" (normal ?)
    - puis la dev-c++ me renvoie une erreur de segmentation fault pour la ligne marque "bug ici"

    j'ai donc un probleme avec et donc je pense que ma maniere de recupere ma class depuis un void* et mauvaise

    j'ai essayer plusieur maniere de faire , mais rien n'a marcher alors je m'en remet a vous merci

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    1°) Je peux voir exactement comment tu appelles add_cmd ? J'ai un doute à propos des chaînes...
    2°) Tu devrais utiliser un typedef pour test pointeurs de fonction: c'est facilement plus lisible
    3°) Pour les chaînes, je te conseillerais d'en stocker une copie dans tes objets (avec strdup() ou en utilisant une std::string...). Ainsi, au moins tu seras sûr qu'on ne passe pas un buffer réutilisé à tes fonctions...

    4°) J'ai trouvé! Erreur dans l'appel à dll_insert: Tu lui passes l'adresse de ton pointeur!
    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
    Rédacteur

    Avatar de khayyam90
    Homme Profil pro
    Architecte de système d’information
    Inscrit en
    Janvier 2004
    Messages
    10 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Architecte de système d’information

    Informations forums :
    Inscription : Janvier 2004
    Messages : 10 371
    Par défaut
    bien le bonsoir,

    le "pas ok" implique logiquement l'erreur de segmentation. Je m'interroge sur la condition de ton while de BWconsol::cmd. size est fixée avant la boucle et jamais réévalué, donc si elle tourne une fois, c'est une boucle qui ne s'arrête jamais et forcément, elle arrivera aux limites de ta liste chainée à un moment ou à un autre.

    ton code c++ ressemble beaucoup à du C. Et je me demande pourquoi tu n'as pas repris une des classes de conteneurs présentes dans le c++, par exemple la std::map qui pourrait tout à fait convenir à tes besoins. Associer une chaine de caractères à un pointeur de fonction, c'est bien ça que tu cherches à faire ?
    Pourquoi réécrire ce qui existe déjà et qui marche très bien ? Tu prends le risque de rencontrer des erreurs.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 3
    Par défaut
    Citation Envoyé par khayyam90
    bien le bonsoir,

    le "pas ok" implique logiquement l'erreur de segmentation. Je m'interroge sur la condition de ton while de BWconsol::cmd. size est fixée avant la boucle et jamais réévalué, donc si elle tourne une fois, c'est une boucle qui ne s'arrête jamais et forcément, elle arrivera aux limites de ta liste chainée à un moment ou à un autre.
    effectivement il y a une erreur au niveau du size qui provoque une boucle infinit (size etant toujours supperieur a 0)
    mais cela ne resout pas le bug ...
    merci quand quand de me l'avoir dit ^^

    Citation Envoyé par khayyam90
    ton code c++ ressemble beaucoup à du C. Et je me demande pourquoi tu n'as pas repris une des classes de conteneurs présentes dans le c++, par exemple la std::map qui pourrait tout à fait convenir à tes besoins. Associer une chaine de caractères à un pointeur de fonction, c'est bien ça que tu cherches à faire ?
    Pourquoi réécrire ce qui existe déjà et qui marche très bien ? Tu prends le risque de rencontrer des erreurs.
    j'utilise plus le c que le c++ , mais il reste quand meme du c++ (avec l'utilisation de class public /private)
    en meme temps je cherche a apprendre ... meme si réinventer la roue me serviras a pas grand chose ... je recode un peu tout ce qui me passe par la main ^^

    Citation Envoyé par Médinoc
    1°) Je peux voir exactement comment tu appelles add_cmd ? J'ai un doute à propos des chaînes...
    a l'origin add_cmd et dans une class BWconsol , voila comme je l'appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    BWconsol STDconsole;
    STDconsole.add_cmd("print",&printff);
    STDconsole.cmd("print");
    Citation Envoyé par Médinoc
    2°) Tu devrais utiliser un typedef pour test pointeurs de fonction: c'est facilement plus lisible
    je verrai ca un peu plus tard ^^

    Citation Envoyé par Médinoc
    3°) Pour les chaînes, je te conseillerais d'en stocker une copie dans tes objets (avec strdup() ou en utilisant une std::string...). Ainsi, au moins tu seras sûr qu'on ne passe pas un buffer réutilisé à tes fonctions...
    desole j'ai pas compris


    Citation Envoyé par Médinoc
    4°) J'ai trouvé! Erreur dans l'appel à dll_insert: Tu lui passes l'adresse de ton pointeur!
    le prototype de dll_insert est : dll_insert (dll_s **, void *);

    ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dll_insert(&commande_stok, &Packcmd);
    &commande_stok et obligatoire sinon il ne modifie pas commande_stok
    et si je remplace &Packcmd par Packcmd le programme plante aussi et au meme endroit


    ------------

    merci pour vos reponse ^^

  5. #5
    Membre chevronné Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Par défaut
    Comme tu travails en C++, il est préférable d'utiliser les std::string.
    Au lieu de faire toi même ton propre conteneur, pourquoi tu n'utilise pas un std::map, tu pourrais ainsi associer à une chaine un pointeur de fonction...
    Inspire toi du Design patern factory...

  6. #6
    Membre chevronné Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Par défaut
    Jette un coup d'oeil dans un bouquin : Modern C++ design d'Andrei Alexandrescu

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 3
    Par défaut
    pas besion j'ai trouver ^^ je te repond puis j'explique

    Citation Envoyé par Rafy
    Comme tu travails en C++, il est préférable d'utiliser les std::string.
    Au lieu de faire toi même ton propre conteneur, pourquoi tu n'utilise pas un std::map, tu pourrais ainsi associer à une chaine un pointeur de fonction...
    je reprend un peu ce que j'ai dit plus haut je souhait refaire les fonction de base tout simple pour apprendre , je pense que j'apprendrais mieux le c/c++ si je m'amuse a refaire les fonction de base (enfin pas toute ^^) que de les utiliser directement

    Citation Envoyé par Rafy
    Inspire toi du Design patern factory...
    desole je sais pas ce que c'est

    --------------
    bon alors mon probleme est resolut je m'explique :
    j'ai modifier cette ligne : Packcmd = (BW_cmd_struc*) dll_data(commande_stok);
    en : *Packcmd = *((BW_cmd_struc*) dll_data(commande_stok));

    j'ai ensuite modifier ma class BW_cmd_struc comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class BW_cmd_struc
    {
        public :
            void (*pt)();
            char* cmd;
            
        BW_cmd_struc& operator=(const BW_cmd_struc &b)
        {
            cmd = b.cmd;
            pt  = b.pt;
            return *this;
        }
    };
    et dans mon add_cmd();
    j'ai modifier ceci : dll_insert(&commande_stok, &Packcmd);
    en ceci : dll_insert(&commande_stok, Packcmd);

    et j'obtient bien le resultat voulut (c'est a dire quand j'appel cmd() avec en parametre une chaine deja enregsitrer elle vme renvoie le fonction associer)

    donc voila ca marche merci a tous ^^

    j'ai juste une fuite de memoire a gerer mais ca c'est simple ...

    bye ^^

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

Discussions similaires

  1. [Etat-Transition] Peut on montrer plus d'une classe dans un diagramme d'état-transition ?
    Par thebloodyman dans le forum Autres Diagrammes
    Réponses: 5
    Dernier message: 12/01/2006, 13h56
  2. Une classe dans une classe...
    Par Baquardie dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 30/09/2005, 19h36
  3. Sauvegarder/Lire une classe dans un fichier
    Par Rodrigue dans le forum C++
    Réponses: 10
    Dernier message: 10/09/2005, 14h12
  4. Réponses: 4
    Dernier message: 10/02/2005, 16h10
  5. [C#] [.NET] Lecture d'une classe dans un fichier
    Par niPrM dans le forum Windows Forms
    Réponses: 4
    Dernier message: 18/05/2004, 08h57

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