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 :

Recupérer valeur pointé par void *


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2013
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Recupérer valeur pointé par void *
    Bonjour,

    J'ai une fonction qui me retourne un void * dans un de mes programmes. Mon problème est que je voudrais récupérer la valeur pointé par ce void*. La seule manière que j'ai trouvé et de caster ce pointeur sur le type de données sur lequel il pointe. Par exemple je sais que mon void * pointe sur un unsigned long. Donc je caste mon void* en unsigned long* et je retrouve ma valeur. Mais dans le cas ou je ne sais pas que c'est un unsigned long comment je peut faire ??

    Merci pour vos réponses !!

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    C'est pour cette raison qu'on évite de traiter des void*.
    En C++ on peut quasiment toujours passer par un équivalent template :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename T>
    T* func()
    {
      return new T;
    }

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par cob59 Voir le message
    C'est pour cette raison qu'on évite de traiter des void*.
    En C++ on peut quasiment toujours passer par un équivalent template :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename T>
    T* func()
    {
      return new T;
    }
    Ceci ne marchera pas, tu ne peux pas avoir deux fonctions de même nom avec les même arguments (ou de même avec les méthodes d'une même classe) qui ne diffèrent que par leur type de retour.

    @guitou99999999 :
    Une des solutions serait de stocker dans une structure le pointeur void et un identifiant qui indiquera le type stocké et retourner ta structure au lieu d'un pointeur void mais ce n'est pas très pratique

    Une autre solution serait, au lieu d'utiliser un void * utiliser un std::string au sein d'une classe avec des méthodes de conversions :
    - implicites : int valeur = monInstance;.
    - explicites : int valeur = (int)monInstance;.
    ou int valeur = monInstance.toInteger(); ou int monEntier ; monInstance.convert(monEntier);.

    On peut aussi ajouter des tests : monInstance.isInteger(); // si la conversion vers un entier est possible.
    Ainsi tu ne pourras pas vraiment savoir le type d'origine mais tu pourras obtenir le "type que tu souhaites".

    Après, difficile de te répondre plus précisément sans plus de détails.

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    @Neckara
    Tu confonds surcharge et spécialisation.
    Ce code fonctionne, et permet de conserver statiquement l'information du type de la donnée allouée, au lieu de la détruire par un cast en void* :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template <typename T>
    T* func()
    {
      return new T;
    }
     
    int* i = func<int>();
    double* d = func<double>();

    --edit--
    Si on t'impose des fonctions qui traitent du void*, il y a toujours la possibilité d'un wrapper. Exemple classique avec des fonctions malloc/free :
    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
     
    // Ce qu'on te fournit
    void* custom_malloc(int type);
    void custom_free(void* ptr, int type);
    int custom_integerType = 1;
    int custom_floatType = 2;
    int custom_doubleType = 3;
     
    // Ton wrapper
    template <T>
    struct Wrapper {
      Wrapper() { ptr = (T*)custom_malloc(CustomType); }
      ~Wrapper() { custom_free(ptr, CustomType); }
      const T& get() const { return *ptr; }
      void set(T& value) { *ptr = value; }
    private:
      T* ptr;
      static int CustomType;
    };
     
    int Wrapper<int>::CustomType = custom_integerType;
    int Wrapper<float>::CustomType = custom_floatType;
    int Wrapper<double>::CustomType = custom_doubleType;
    (...)
     
    Wrapper<int> a;
    a.set(42);
     
    cout << a.get() << endl;
    Pas testé, mais l'idée est là.
    La classe Wrapper est simplissime d'utilisation, et tu évites les mauvaises (dés)alloc.

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Mea culpa,

    Par contre, tu ne réponds pas au problème de l'utilisateur car tu pars du principe qu'il sait, lorsqu'il appelle sa fonction quel type sera retournée/doit être retourné. Ce qui n'est pas le cas.

    EDIT :
    L'idée de Wrapper est pas mal, mais en fonction de l'algorithme du posteur, il est possible que cette méthode ne marche pas.

    Si on veut retourner un "Wrapper" au sein d'une fonction, on ne pourra pas vraiment (on se ramènerait au problème originel).

    Dans ce cas, il faudrait créer une classe Mere dont Wrapper hériterait.
    Puis caster Wrapper en fonction des informations contenus dans Mere.

    Or, on peut aussi penser à fournir dans Mere des méthodes virtuelles isMachin(), etc...
    Ce qui nous ramènerait à ma seconde solutions (en dérivant pour "optimiser" certaines méthodes en fonctions de certains types particuliers).

    EDIT : par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Type foo(void)
    {
          if(...)
                   return int(2);
          if(....)
                   return float(4);
    }
    EDIT :
    Je viens d'y penser mais une solution pourrait aussi être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct{
             union{
                        int i;
                        float f;
            }
     
             TypeId id;
    }

  6. #6
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2013
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2013
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Merci de vos réponses !!

    De ce que je comprends il n'y a pas de méthode simple. Je vais étudier tout ça !!

  7. #7
    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
    C'est le principe du Variant: Une union plus son type.

    Je crois que Boost (et peut-être même C++11) expose un tel template, permettant de faire un variant sur un ensemble de types.
    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.

Discussions similaires

  1. Sauvegarde d'images valeur point par point
    Par betaplus dans le forum C++
    Réponses: 6
    Dernier message: 25/02/2015, 10h54
  2. Echec de stockage d'une valeur dans une variable locale pointée par EBP
    Par homeostasie dans le forum x86 32-bits / 64-bits
    Réponses: 1
    Dernier message: 16/12/2008, 13h52
  3. Réponses: 3
    Dernier message: 29/07/2008, 09h56
  4. [Débutant][C++] Valeur renvoyée par un void
    Par hm1ch dans le forum C++
    Réponses: 4
    Dernier message: 11/10/2007, 22h28
  5. Réponses: 3
    Dernier message: 17/03/2006, 14h50

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