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 :

passer un parametre dans un void *


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Bonjour,

    Je dois écrire une fonction qui doit être de la forme ma_fonction(void * param) car son appel sera géré par une autre fonction qui enregistre les paramètre sous la forme void * puis appelle ensuite la fonction avec ce paramètre.

    Je voudrai que ma_fonction reçoive un int comme paramètre et puisse y accéder.
    Comment faire?

    Merci

    Pour préciser un peu (c'est pas facile a expliquer), je voudrai que ca ressemble a ca, qui doit etre faux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void ma_fonction (void * param) {
    int mon_int = (int)param;
    }
    Si ma fonction d'appel ressemble a ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void fonction_appelante(void *Fonction,void *Param);
    Et lorsque je demanderai a la fonction d'apel d'enregistrer le parametre a envoyer a ma_fonction je lui passerai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int i = 0;
    fonction_appelante(ma_fonction,i);

  2. #2
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 306
    Points
    5 306
    Par défaut
    2 / si l'appelant founit un int

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void ma_fonction(void * param) 
    {
        int value = (int) param;
    }
    T'auras surement un warning au niveau du compilo, mais cela fonctionnera..

    2 /si l'appelant founit un int *

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void ma_fonction(void * param) 
    {
        int *value = (int *) param;
    }

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    l'appelant fournit un void *
    C'est moi qui veux fournir a l'appelant un int qu'il me redonnera sous forme de void * :
    void fonction_appelante(void *Fonction,void *Param);

  4. #4
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 306
    Points
    5 306
    Par défaut
    Ca serait mieux si tu pouvais lui passer un int * car dans ce cas le cast est plus propre et plus logique !

  5. #5
    Membre averti Avatar de cmoibal
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Avril 2007
    Messages : 361
    Points : 414
    Points
    414
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    l'appelant fournit un void *
    C'est moi qui veux fournir a l'appelant un int qu'il me redonnera sous forme de void * :
    void fonction_appelante(void *Fonction,void *Param);
    je ne sais pas, mais si la fonction_appelante attend toujours un int, alors il auras pas de problème; il suffit d'affecter le pointeur void * avec ce lui de l'entier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void ma_fonction(void * param) 
    {
        int *retValue;
        retValue = malloc(sizeof(int));
        ....
        *retValue = value;
        param = retValue;
    }
    Pour la fonction appelante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void fonction_appelante(void *Function, void *param) {
    int retValue;
    Function(param);
    retValue = (int *) param;
    ....
    }

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    ma fonction appelante est une fonction générique qui peut apeller d'autres fonctions avec différents type de paramètres. De plus ce n'est pas moi qui l'ai écrite et c'est une fonction existante.
    Donc quelle est la syntaxe pour passer un int? ou faut il obligatoirement passer un int * ?

  7. #7
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Apparemment,fonction_appelanteprend pour premier argument une fonction. Le type de cet argument est incorrect. On devrait avoir logiquement quelque chose suivant la trame ci-dessous :

    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
    void ma_fonction (void * param)
    {
       int mon_int = *(int*)param;
    //.....
    }
     
    void fonction_appelante(void (*Fonction)(void*),void *Param)
    {
    //....
       Fonction(Param);
    //....
    }
     
    int main(void)
    {
       int i =123;
       fonction_appelante(ma_fonction,&i);
       return 0;
    }

  8. #8
    Membre averti Avatar de cmoibal
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Avril 2007
    Messages : 361
    Points : 414
    Points
    414
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    ma fonction appelante est une fonction générique qui peut apeller d'autres fonctions avec différents type de paramètres. De plus ce n'est pas moi qui l'ai écrite et c'est une fonction existante.
    Donc quelle est la syntaxe pour passer un int? ou faut il obligatoirement passer un int * ?
    Donc, il te faut juste un cast sur l'entier, mais il faut que la fonction appelé soit adapter pour qu'elle gére les entier à partie d'un void.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(void) {
    int value;
    fonction_appelante(ma_fonction, (void *)&value);
    return 0;
    }
     
    void ma_fonction(void *param) {
    int value = *((int *)param); //si tu utilise un argument input
    .....
    param = value // si tu utilise un argument output
    }

  9. #9
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 306
    Points
    5 306
    Par défaut
    Citation Envoyé par cmoibal Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void ma_fonction(void * param) 
    {
        int *retValue;
        retValue = malloc(sizeof(int));
        ....
        *retValue = value;
        param = retValue;
    }
    Tu te rends compte de ce que tu écris ??????

    ne sert a rien car param n'est pas modifié en retour de fonction

    Et puis pourquoi allouer de la mémoire car elle ne sera pas libérée...

    pasdeface, tu passes un int ou un int * à la fonction et tu castes dans la fonction..

    C'est toi qui ecris les deux fonctions ? ou sinon laquelle ? Soit plus clair

  10. #10
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 306
    Points
    5 306
    Par défaut
    Suis la solution de diogene

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Citation Envoyé par diogene Voir le message
    Apparemment,fonction_appelanteprend pour premier argument une fonction. Le type de cet argument est incorrect.
    En fait elle enregistre la fonction dans une structure pour pouvoir la rapeller ensuite.
    Donc les paramètres de fonction_apellante sont déclarés comme ça :
    (void *Fonction,void *Param)
    Et Fonction est la fonction a rappeler plus tard. Elle est enregistrée dans une structure déclarée comme ca :
    int (*pFcontion)(void *);
    (elle renvoie en fait un int mais peut importe le problème n'est pas là).
    C'est toujours incorrect? En tout cas ca marche bien pour les autres fonctions déjà crées et qui l'utilisent.

    Citation Envoyé par vicenzo
    C'est toi qui ecris les deux fonctions ? ou sinon laquelle ? Soit plus clair
    Je l'ai dit pourtant :
    " ma fonction appelante est une fonction générique qui peut appeler d'autres fonctions avec différents type de paramètres. De plus ce n'est pas moi qui l'ai écrite et c'est une fonction existante."
    J'ai écrit seulement ma_fonction.

    Je vais donc suivre la solution de diogene qui a l'air de bien correspondre à ce dont j'ai besoin, et je vous dirai si ca marche.

    Merci beaucoup !

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    J'ai une question par rapport a la solution de diogene :
    Si je suis dans une fonction F1 lorsque j'appelle fonction_apellante, et que je lui donne l'adresse d'un int, le problème c'est que lorsque je vais quitter F1 ce int va etre détruit, et lorsque plus tard fonction_appelante va appeler ma_fonction avec l'adresse du int, il n'existera plus, non?

    Edit :
    Bon je pense que oui, donc la solution que je vois serai de faire un malloc pour me réserver la place mémoire pour mon int, et lorsque ma fonction est appelée je fait un free sur mon paramètre.

    Ça vous semble correct?

    merci

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void ma_fonction (void * param) {
    int mon_int = (int)param;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void fonction_appelante(void *Fonction,void *Param);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int i = 0;
    fonction_appelante(ma_fonction,i);
    Un paramètre générique void * est fait pour passer une adresse de variable et rien d'autre. Il faut que ce soit absolument clair. un int n'est pas compatible avec une adresse.

    Une solution est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void ma_fonction (void * param) {
    int *p_int = param;
    int mon_int = *p_int;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void fonction_appelante(void *Fonction,void *Param);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int i = 0;
    fonction_appelante(ma_fonction,&i);

  14. #14
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par cmoibal Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int main(void) {
    int value;
    fonction_appelante(ma_fonction, (void *)&value);
    return 0;
    }
    Horriblement faux. La conversion int -> void* n'est pas garantie en C. Le comportement est indéterminé (pour simplifier).

  15. #15
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    Ça vous semble correct?
    Si le risque est avéré (threads, par exemple), oui.

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Un paramètre générique void * est fait pour passer une adresse de variable et rien d'autre.
    oui j'avais bien dis "je voudrai que ça ressemble a ça, qui doit être faux".
    Je voulais connaitre la manière correcte de procéder, et je penses donc avoir ma réponse, j'essaye ca.
    Merci

  17. #17
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 306
    Points
    5 306
    Par défaut
    C'est pour cela que diogene et moi lui ont indiqué de passer un int * à sa fonction....

    Emmanuel, tu peux écrire plus gros ?

Discussions similaires

  1. [JSF] passer un parametre dans un popup
    Par maximus001ma dans le forum JSF
    Réponses: 5
    Dernier message: 07/08/2009, 18h16
  2. passer un parametre dans select count
    Par esojrehcir dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 26/10/2007, 14h12
  3. passer deux parametres dans navigateurl d'une datalist
    Par imanesl dans le forum ASP.NET
    Réponses: 2
    Dernier message: 24/04/2007, 10h40
  4. faire passer des parametres dans l'url
    Par Freyja dans le forum Réseau/Web
    Réponses: 2
    Dernier message: 21/08/2006, 15h57

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