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 :

problème avec implémentation de fonctions callbacks


Sujet :

C++

  1. #1
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut problème avec implémentation de fonctions callbacks
    Bonjour à tous,

    pour des raisons qui échappent à ma volonté (malheureusement), je me vois contraint d'implémenter des trucs tordus en ce moment.

    Donc, pour expliquer mon souci:
    j'ai un main qui ressemble à ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void macallback(char* message)
    {
        cout << message << endl;
    }
     
    int main(char* argv, char** argc)
    {
        Connector connector;
        connector.sendText("toto", macallback);
    }
    et voici la définition de Connector::sendText():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int Connector::sendText(std::string, void callback(char*));
    Jusqu'ici, tout va bien.
    Maintenant, il se trouve que dans Connector::sendText, je dois appeler une fonction (de libcurl) qui prend elle-même une callback. J'appelerais cette dernière curlCB. Et je voudrais que ma callback à moi, la mienne, soit appelée dans la callback curlCB.

    J'ai tenté le code suivant:
    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
    struct MyParam
    {
       std::string str;
       void CBack(char*);
    }
     
    void curlCB(void* userParam)
    {
       struct MyParam *param= (struct MyParam*) userParam;
       param->CBack( param.str.c_str() );
    }
     
    int Connector::sendText(std::string, void callback(char*))
    {
       // je créé le param que je vais passer à la curlCB
       MyParam param;
       param.CBack = callback; // <---- pb ici
     
       // je configure curl
       curl_easy_setopt(m_pCurl, CURLOPT_READFUNCTION, curlCB); //je lui passe ma callback
       curl_easy_setopt(m_pCurl, CURLOPT_READDATA, &param); //je passe le paramètre de la callback (curlCB)
    }
    Le problème, et bien c'est que ça ne compile pas.
    La ligne param.CBack = callback me renvoie l'erreur:
    error C2659: '=' : fonction comme opérande gauche
    Mais justement, c'est ce que je veux: que ma fonction soit l'opérande gauche. Mais visiblement, je n'en ai pas le droit. Alors comment faire?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Points : 307
    Points
    307
    Par défaut
    La définition de MyParam::CBack est incorrecte : tu déclares une fonction, et non pas un pointeur sur une fonction. Remplace cette déclaration (et les autres) par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void (*CBack)(char*);
    et ça devrait marcher.

  3. #3
    Membre expert
    Avatar de hiko-seijuro
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 011
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 011
    Points : 3 065
    Points
    3 065
    Par défaut
    ca serait pas plutot ca que devrait etre ta struct :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct MyParam
    {
       std::string str;
       void (*CBack)(char*);
    }
    Hiko-seijuro

    n'cha - hoyoyo gang

    espace perso : http://hiko-seijuro.developpez.com
    dernier tuto : Introduction à l'éditeur de texte Emacs sous linux
    consulter les faqs : http://www.developpez.com/faq
    PAS DE QUESTIONS TECHNIQUES PAR MP OU MAIL

  4. #4
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Joli chassé-croisé
    Et en plus, ça marche impec

    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  5. #5
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Argh, j'ai un autre problème à vous soumettre:

    Sachant que quelques lignes de codes valent mieux que des pages d'explications, j'ai fait un exemple de ce qui me pose problème:
    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
    #include <iostream>
     
    using namespace std;
     
    // je déclare le type de ma callback
    typedef void (*UserCallback)(const char*);
     
    // la callback
    void MaCallBack(const char* str)
    {
    	cout << str << endl;
    }
     
    // la fonction qui appelle la callback
    void func1(void* userp)
    {
    	UserCallback callback = (UserCallback) &userp;
    	callback("toto"); // <--- plantage ici!
    }
     
    int main(char* argc, char** argv)
    {
    	func1(MaCallBack);
     
    	getchar();
    	return 0;
    }
    Le problème: ça plante à l'appel de la callback: "access violation".
    Vous comprenez ce qu'il se passe?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  6. #6
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Ok j'ai trouvé:
    ma callback c'est un void*, donc il faut que je garde le type du paramètre dans func1:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void func1(void* userp)
    {
    	UserCallback callback = (UserCallback) userp;
    	callback("toto");
    }
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Des void* ? Des casts ? Des pointeurs de fonction ? Tu fais du C ou quoi ?

    En plus, tu castes un pointeur de données en pointeur de fonction... C'est de l'UB.
    Boost ftw

  8. #8
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Oui je sais, c'est une horreur. Mais je n'ai pas le choix. Je dois faire le lien entre plusieurs "briques" et je n'ai aucune marge de manoeuvre.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

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

Discussions similaires

  1. jquery avec ajax et fonction callback
    Par guiguiz dans le forum jQuery
    Réponses: 2
    Dernier message: 18/03/2012, 03h52
  2. Problème avec appel de fonction!
    Par Olivier_Magny dans le forum Débuter
    Réponses: 1
    Dernier message: 10/10/2010, 23h54
  3. Problème avec implémentation perceptron
    Par sancelot dans le forum Méthodes prédictives
    Réponses: 1
    Dernier message: 05/02/2010, 01h01
  4. [MySQL] Problème avec le fichier fonction.php
    Par cbirou dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 23/12/2009, 15h54
  5. Problème avec une petite fonction toute bête
    Par jeremy13 dans le forum MATLAB
    Réponses: 3
    Dernier message: 18/01/2007, 09h10

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